diff --git a/404.html b/404.html new file mode 100644 index 00000000..53884c81 --- /dev/null +++ b/404.html @@ -0,0 +1,30 @@ + + + + + + CodeceptJS + + + + + + + + + + + + + + + + +

404

Looks like we've got some broken links.
Take me home.
+ + + diff --git a/CNAME b/CNAME new file mode 100644 index 00000000..d3a3a5ac --- /dev/null +++ b/CNAME @@ -0,0 +1 @@ +codecept.io diff --git a/acceptance/index.html b/acceptance/index.html new file mode 100644 index 00000000..ff28a187 --- /dev/null +++ b/acceptance/index.html @@ -0,0 +1,291 @@ + + + + + + Acceptance Testing | CodeceptJS + + + + + + + + + + + + + + + + +
Acceptance Testing

# Acceptance Testing

How does your client, manager, or tester, or any other non-technical person, know your web application is working? By opening the browser, accessing a site, clicking on links, filling in the forms, and actually seeing the content on a web page.

Acceptance (also called End to End) tests can cover standard but complex scenarios from a user's perspective. With acceptance tests you can be confident that users, following all defined scenarios, won't get errors. We check not just functionality of application but a user interface (UI) as well.

By default CodeceptJS uses WebDriver helper and Selenium to automate browser. Within web page you can locate elements, interact with them, and check that expected elements are present on a page. +However, you can also choose Puppeteer, Nightmare or Protractor helpers, driven by corresponding libraries. +No matter of helper and library you use for acceptance testing, CodeceptJS should execute same actions in similar manner.

In case of CodeceptJS you can be sure that in code it will be as easy as it sounds. You just describe a test scenario with JavaScript DSL and allow the framework to handle the rest.

Within web page you can locate elements, interact with them, and check that expected elements are present on a page. That is what a test look like. +That is what a test look like.

I.amOnPage('/login');
+I.fillField('Username', 'john');
+I.fillField('Password', '123456');
+I.click('Login');
+I.see('Welcome, John');
+

This is how we can check that login form of a simple web application works. At first we opened /login page, then filled forms and in the end we saw the greetings text.

# Locating Element

Element can be found by CSS or XPath locators. Practically every steps +in WebDriver helper accept them both.

I.seeElement('.user'); // element with CSS class user
+I.seeElement('//button[contains(., "press me")]'); // button
+

By default CodeceptJS tries to guess the locator type. +In order to specify exact locator type you can pass a hash called strict locator.

I.seeElement({css: 'div.user'});
+I.seeElement({xpath: '//div[@class=user]'});
+

Strict locators allow to specify additional locator types:

// locate form element by name
+I.seeElement({name: 'password'});
+// locate element by id
+I.seeElement({permalink: /'users'});
+

In mobile testing (opens new window) you can use ~ to specify accessibility id to locate an element. In web application you can locate element by their aria-label value.

// locate element by [aria-label] attribute in web
+// or by accessibility id in mobile
+I.seeElement('~username');
+

# Clicking

CodeceptJS provides a flexible syntax to specify an element to click.

By default CodeceptJS tries to find button or link with exact text on it

// search for link or button
+I.click('Login');
+

If none found, CodeceptJS tries to find link or button containing that text. In case an image is clickable its alt attribute will be checked for text inclusion. Form buttons will also be searched by name.

To narrow down the results you can specify a context in second parameter.

I.click('Login', '.nav'); // search only in .nav
+I.click('Login', {css: 'footer'}); // search only in footer
+

To skip the global search pass exact strict locator (or start locator with // or . or #). +In this case you are not limited to buttons and links. Any element found by that locator is clicked.

// click element by CSS
+I.click('#signup');
+// click element located by name inside a form
+I.click({name: 'submit'}, '#user>form');
+

# Filling Fields

Clicking the links is not what takes the most time during testing a web site. If your site consists only of links you can skip test automation. The most routine waste of time goes into the testing of forms. CodeceptJS provides several ways of doing that.

Let's submit this sample form for a test:

<form method="post" action="/update" id="update_form">
+     <label for="user_name">Name</label>
+     <input type="text" name="user[name]" id="user_name" />
+     <label for="user_email">Email</label>
+     <input type="text" name="user[email]" id="user_email" />
+     <label for="user_gender">Gender</label>
+     <select id="user_gender" name="user[gender]">
+          <option value="m">Male</option>
+          <option value="f">Female</option>
+     </select>
+     <input type="submit" name="submitButton" value="Update" />
+</form>
+

We need to fill in all those fields and click "Update" button. CodeceptJS matches form elements by their label, name, or by CSS or XPath locators.

// we are using label to match user_name field
+I.fillField('Name', 'Miles');
+// we can use input name
+I.fillField('user[email]','miles@davis.com');
+// select element by label, choose option by text
+I.selectOption('Gender','Male');
+// click 'Update' button, found by text
+I.click('Update');
+

Alternative scenario:

// we are using CSS
+I.fillField('#user_name', 'Miles');
+I.fillField('#user_email','miles@davis.com');
+// select element by label, option by value
+I.selectOption('#user_gender','m');
+// click 'Update' button, found by name
+I.click('submitButton', '#update_form');
+

To fill in sensitive data use secret function:

I.fillField('password', secret('123456'));
+

# Assertions

In order to verify the expected behavior of a web application, web page connects should be checked. +CodeceptJS provides built-in assertions for that. They start with see (or dontSee) prefix, as they describe user's current vision.

The most general and common assertion is see:

// Just a visible text on a page
+I.see('Hello');
+// text inside .msg element
+I.see('Hello', '.msg');
+// opposite
+I.dontSee('Bye');
+

You should provide a text as first argument, and optionally a locator to narrow the search context.

You can check that specific element exists (or not) on a page, as it was described in Locating Element section.

I.seeElement('.notice');
+I.dontSeeElement('.error');
+

Additional assertions:

I.seeInCurrentUrl('/user/miles');
+I.seeInField('user[name]', 'Miles');
+I.seeInTitle('My Website');
+

To see all possible assertions see the helper's reference.

# Grabbing

Sometimes you need to retrieve a data from a page to use it in next steps of a scenario. +Imagine, application generates a password and you want to ensure that user can login using this password.

Scenario('login with generated password', async (I) => {
+  I.fillField('email', 'miles@davis.com');
+  I.click('Generate Password');
+  const password = await I.grabTextFrom('#password');
+  I.click('Login');
+  I.fillField('email', 'miles@davis.com');
+  I.fillField('password', password);
+  I.click('Log in!');
+  I.see('Hello, Miles');
+});
+

grabTextFrom action is used here to retrieve text from an element. All actions starting with grab prefix are expected to return data. In order to synchronize this step with a scenario you should pause test execution with await keyword of ES6. To make it work your test should be written inside a async function (notice async in its definition).

Scenario('use page title', async (I) => {
+  // ...
+  const password = await I.grabTextFrom('#password');
+  I.fillField('password', password);
+});
+

# Waiting

In modern web applications rendering is happen on client side. +Sometimes that may cause delays. A test may fail while trying to click an element which has not appeared on a page yet. +To handle this cases wait* methods introduced.

I.waitForElement('#agree_button', 30); // secs
+// clicks a button only when it is visible
+I.click('#agree_button');
+

More wait actions can be found in helper's reference.

# SmartWait

It is possible to wait for elements pragmatically. If a test uses element which is not on a page yet, CodeceptJS will wait for few extra seconds before failing. This feature is based on Implicit Wait (opens new window) of Selenium. CodeceptJS enables implicit wait only when searching for a specific element and disables in all other cases. Thus, the performance of a test is not affected.

SmartWait can be enabled by setting wait option in WebDriver config. +Add "smartWait": 5000 to wait for additional 5s.

SmartWait works with a CSS/XPath locators in click, seeElement and other methods. See where it is enabled and where is not:

I.click('Login'); // DISABLED, not a locator
+I.fillField('user', 'davert'); // DISABLED, not a specific locator
+I.fillField({name: 'password'}, '123456'); // ENABLED, strict locator
+I.click('#login'); // ENABLED, locator is CSS ID
+I.see('Hello, Davert'); // DISABLED, Not a locator
+I.seeElement('#userbar'); // ENABLED
+I.dontSeeElement('#login'); // DISABLED, can't wait for element to hide
+I.seeNumberOfElements('button.link', 5); // DISABLED, can wait only for one element
+
+

SmartWait doesn't check element for visibility, so tests may fail even element is on a page.

Usage example:

// we use smartWait: 5000 instead of
+// I.waitForElement('#click-me', 5);
+// to wait for element on page
+I.click('#click-me');
+

If it's hard to define what to wait, it is recommended to use retries to rerun flaky steps.

# IFrames

within operator can be used to work inside IFrames. Special frame locator is required to locate the iframe and get into its context.

See example:

within({frame: "#editor"}, () => {
+  I.see('Page');
+});
+

Nested IFrames can be set by passing array (WebDriver, Nightmare & Puppeteer only):

within({frame: [".content", "#editor"]}, () => {
+  I.see('Page');
+});
+

# Auto Login

To share the same user session across different tests CodeceptJS provides autoLogin plugin. It simplifies login management and reduces time consuming login operations. Instead of filling in login form before each test it saves the cookies of a valid user session and reuses it for next tests. If a session expires or doesn't exist, logs in a user again.

This plugin requires some configuration but is very simple in use:

Scenario('do something with logged in user', (I, login)) => {
+  login('user');
+  I.see('Dashboard','h1');
+});
+

With autoLogin plugin you can save cookies into a file and reuse same session on different runs.

Read more about setting up autoLogin

# Multiple Sessions

CodeceptJS allows to run several browser sessions inside a test. This can be useful for testing communication between users inside a system, for instance in chats. To open another browser use session() function as shown in example:

Scenario('test app', (I) => {
+  I.amOnPage('/chat');
+  I.fillField('name', 'davert');
+  I.click('Sign In');
+  I.see('Hello, davert');
+  session('john', () => {
+    // another session started
+    I.amOnPage('/chat');
+    I.fillField('name', 'john');
+    I.click('Sign In');
+    I.see('Hello, john');
+  });
+  // switching back to default session
+  I.fillField('message', 'Hi, john');
+  // there is a message from current user
+  I.see('me: Hi, john', '.messages');
+  session('john', () => {
+    // let's check if john received it
+    I.see('davert: Hi, john', '.messages');
+  });
+});
+

session function expects a first parameter to be a name of a session. You can switch back to session by using the same name.

You can override config for session by passing second parameter:

session('john', { browser: 'firefox' } , () => {
+  // run this steps in firefox
+  I.amOnPage('/');
+});
+

or just start session without switching to it. Call session passing only its name:

Scenario('test', (I) => {
+  // opens 3 additional browsers
+  session('john');
+  session('mary');
+  session('jane');
+
+  I.amOnPage('/');
+
+  // switch to session by its name
+  session('mary', () => {
+    I.amOnPage('/login');
+  });
+}
+

session can return value which can be used in scenario:

// inside async function
+const val = await session('john', () => {
+  I.amOnPage('/info');
+  return I.grabTextFrom({ css: 'h1' });
+});
+I.fillField('Description', val);
+

Function passed into session can use I, page objects, and any objects declared for the scenario. +This function can also be declared as async (but doesn't work as generator).

Also, you can use within inside a session but you can't call session from inside within.

# Multiple Windows

CodeceptJS allows to use several browser windows inside a test. Sometimes we are testing the functionality of websites that we cannot control, such as a closed-source managed package, and there are popups that either remain open for configuring data on the screen, or close as a result of clicking a window. We can use these functions in order to gain more control over which page is being tested with Codecept at any given time. For example:

const assert = require('assert');
+
+Scenario('should open main page of configured site, open a popup, switch to main page, then switch to popup, close popup, and go back to main page', async (I) => {
+    I.amOnPage('/');
+    const handleBeforePopup = await I.grabCurrentWindowHandle();
+    const urlBeforePopup = await I.grabCurrentUrl();
+    const allHandlesBeforePopup = await I.grabAllWindowHandles();
+    assert.equal(allHandlesBeforePopup.length, 1, 'Single Window');
+
+    await I.executeScript(() => {
+        window.open('https://www.w3schools.com/', 'new window', 'toolbar=yes,scrollbars=yes,resizable=yes,width=400,height=400');
+    });
+
+    const allHandlesAfterPopup = await I.grabAllWindowHandles();
+    assert.equal(allHandlesAfterPopup.length, 2, 'Two Windows');
+
+    await I.switchToWindow(allHandlesAfterPopup[1]);
+    const urlAfterPopup = await I.grabCurrentUrl();
+    assert.equal(urlAfterPopup, 'https://www.w3schools.com/', 'Expected URL: Popup');
+
+    assert.equal(handleBeforePopup, allHandlesAfterPopup[0], 'Expected Window: Main Window');
+    await I.switchToWindow(handleBeforePopup);
+    const currentURL = await I.grabCurrentUrl();
+    assert.equal(currentURL, urlBeforePopup, 'Expected URL: Main URL');
+
+    await I.switchToWindow(allHandlesAfterPopup[1]);
+    const urlAfterSwitchBack = await I.grabCurrentUrl();
+    assert.equal(urlAfterSwitchBack, 'https://www.w3schools.com/', 'Expected URL: Popup');
+    await I.closeCurrentTab();
+
+    const allHandlesAfterPopupClosed = await I.grabAllWindowHandles();
+    assert.equal(allHandlesAfterPopupClosed.length, 1, 'Single Window');
+    const currentWindowHandle = await I.grabCurrentWindowHandle();
+    assert.equal(currentWindowHandle, allHandlesAfterPopup[0], 'Expected Window: Main Window');
+
+}).tag('@ProofOfConcept').tag('@grabAllWindowHandles').tag('@grabCurrentWindowHandle').tag('@switchToWindow');
+
Last Updated: 1/10/2020, 6:48:42 PM
+ + + diff --git a/advanced/index.html b/advanced/index.html new file mode 100644 index 00000000..3a9e1163 --- /dev/null +++ b/advanced/index.html @@ -0,0 +1,250 @@ + + + + + + Advanced Usage | CodeceptJS + + + + + + + + + + + + + + + + +
Advanced Usage

# Advanced Usage

# Data Driven Tests

Execute the same scenario on a different data set.

Let's say you want to test login for different user accounts. +In this case, you need to create a datatable and fill it in with credentials. +Then use Data().Scenario to include this data and generate multiple scenarios:

// Define data table inside a test or load from another module
+let accounts = new DataTable(['login', 'password']); //
+accounts.add(['davert', '123456']); // adding records to a table
+accounts.add(['admin', '123456']);
+
+// You can skip some data. But add them to report as skipped (just like with usual scenarios):
+accounts.xadd(['admin', '23456'])
+
+// Pass dataTable to Data()
+// Use special param `current` to get current data set
+Data(accounts).Scenario('Test Login', ({ I, current }) => {
+  I.fillField('Username', current.login); // current is reserved!
+  I.fillField('Password', current.password);
+  I.click('Sign In');
+  I.see('Welcome '+ current.login);
+});
+
+
+// Also you can set only for Data tests. It will launch executes only the current test but with all data options
+Data(accounts).only.Scenario('Test Login', ({ I, current }) => {
+  I.fillField('Username', current.login); // current is reserved!
+  I.fillField('Password', current.password);
+  I.click('Sign In');
+  I.see('Welcome '+ current.login);
+});
+

Important: you can't use name current for pageObjects or helpers in data scenarios

This will produce 2 tests with different data sets. +Current data set is appended to a test name in output:

✓ Test Login | {"login":"davert","password":"123456"}
+✓ Test Login | {"login":"admin","password":"123456"}
+S Test Login | {"login":"admin","password":"23456"}
+
// You can filter your data table
+Data(accounts.filter(account => account.login == 'admin')
+.Scenario('Test Login', ({ I, current }) => {
+  I.fillField('Username', current.login);
+  I.fillField('Password', current.password);
+  I.click('Sign In');
+  I.see('Welcome '+ current.login);
+});
+

This will limit data sets accoring passed function:

✓ Test Login | {"login":"admin","password":"123456"}
+S Test Login | {"login":"admin","password":"23456"}
+

Data sets can also be defined with array, generator, or a function.

Data(function*() {
+  yield { user: 'davert'};
+  yield { user: 'andrey'};
+}).Scenario() // ...
+

HINT: If you don't use DataTable. add toString() method to each object added to data set, so the data could be pretty printed in a test name

# Tags

Append @tag to your test name, so

Scenario('update user profile @slow')
+

Alternativly, use tag method of Scenario to set additional tags:

Scenario('update user profile', ({  }) => {
+  // test goes here
+}).tag('@slow').tag('important');
+

All tests with @tag could be executed with --grep '@tag' option.

codeceptjs run --grep '@slow'
+

Use regex for more flexible filtering:

  • --grep '(?=.*@smoke2)(?=.*@smoke3)' - run tests with @smoke2 and @smoke3 in name
  • --grep "\@smoke2|\@smoke3" - run tests with @smoke2 or @smoke3 in name
  • --grep '((?=.*@smoke2)(?=.*@smoke3))|@smoke4' - run tests with (@smoke2 and @smoke3) or @smoke4 in name
  • --grep '(?=.*@smoke2)^(?!.*@smoke3)' - run tests with @smoke2 but without @smoke3 in name
  • --grep '(?=.*)^(?!.*@smoke4)' - run all tests except @smoke4

# Debug

CodeceptJS provides a debug mode in which additional information is printed. +It can be turned on with --debug flag.

npx codeceptjs run --debug
+

to receive even more information turn on --verbose flag:

npx codeceptjs run --verbose
+

You can pause execution and enter interactive console mode by calling pause() inside your test.

To see a complete internal debug of CodeceptJS use DEBUG env variable:

DEBUG=codeceptjs:* npx codeceptjs run
+

For an interactive debugging use NodeJS debugger. In WebStorm:

node $NODE_DEBUG_OPTION ./node_modules/.bin/codeceptjs run
+

For Visual Studio Code, add the following configuration in launch.json:

{
+  "type": "node",
+  "request": "launch",
+  "name": "codeceptjs",
+  "args": ["run", "--grep", "@your_test_tag"],
+  "program": "${workspaceFolder}/node_modules/codeceptjs/bin/codecept.js"
+}
+

# Test Options

Features and Scenarios have their options that can be set by passing a hash after their names:

Feature('My feature', {key: val});
+
+Scenario('My scenario', {key: val},({ I }) => {});
+

You can use this options for build your own plugins (opens new window) with event listners (opens new window). Example:

  // for test
+  event.dispatcher.on(event.test.before, (test) => {
+    ...
+    if (test.opts.key) {
+      ...
+    }
+    ...
+  });
+  // or for suite
+  event.dispatcher.on(event.suite.before, (suite) => {
+    ...
+    if (suite.opts.key) {
+      ...
+    }
+    ...
+  });
+

# Timeout

Tests can get stuck due to various reasons such as network connection issues, crashed browser, etc. +This can make tests process hang. To prevent these situations timeouts can be used. Timeouts can be set explicitly for flaky parts of code, or implicitly in a config.

Previous timeout implementation was disabled as it had no effect when dealing with steps and promises.

# Steps Timeout

It is possible to limit a step execution to specified time with I.limitTime command. +It will set timeout in seconds for the next executed step:

// limit clicking to 5 seconds
+I.limitTime(5).click('Link')
+

It is possible to set a timeout for all steps implicitly (except waiters) using stepTimeout plugin.

# Tests Timeout

Test timeout can be set in seconds via Scenario options:

// limit test to 20 seconds
+Scenario('slow test that should be stopped', { timeout: 20 }, ({ I }) => {
+  // ...
+})
+

This timeout can be set globally in codecept.conf.js in seconds:

exports.config = {
+
+  // each test must not run longer than 5 mins
+  timeout: 300,
+
+}
+

# Suites Timeout

A timeout for a group of tests can be set on Feature level via options.

// limit all tests in this suite to 30 seconds
+Feature('flaky tests', { timeout: 30 })
+

# Timeout Confguration

Updated in 3.4

Timeout rules can be set globally via config.

To set a timeout for all running tests provide a number of seconds to timeout config option:

// inside codecept.conf.js or codecept.conf.ts
+timeout: 30, // limit all tests in all suites to 30 secs
+

It is possible to tune this configuration for a different groups of tests passing options as array and using grep option to filter tests:

// inside codecept.conf.js or codecept.conf.ts
+
+timeout: [
+  10, // default timeout is 10secs  
+
+  // but increase timeout for slow tests
+  {
+    grep: '@slow',
+    Feature: 50
+  },
+]
+

ℹ️ grep value can be string or regexp

It is possible to set a timeout for Scenario or Feature:

// inside codecept.conf.js or codecept.conf.ts
+timeout: [
+
+  // timeout for Feature with @slow in title
+  {
+    grep: '@slow',
+    Feature: 50
+  },
+  
+  // timeout for Scenario with 'flaky0' .. `flaky1` in title
+  {
+    // regexp can be passed to grep
+    grep: /flaky[0-9]/,
+    Scenario: 10
+  },
+
+  // timeout for all suites
+  {    
+    Feature: 20
+  }
+]
+

Global timeouts will be overridden by explicit timeouts of a test or steps.

# Disable Timeouts

To execute tests ignoring all timeout settings use --no-timeouts option:

npx codeceptjs run --no-timeouts
+

# Dynamic Configuration

Helpers can be reconfigured per scenario or per feature. +This might be useful when some tests should be executed with different settings than others. +In order to reconfigure tests use .config() method of Scenario or Feature.

Scenario('should be executed in firefox', ({ I }) => {
+  // I.amOnPage(..)
+}).config({ browser: 'firefox' })
+

In this case config overrides current config of the first helper. +To change config of specific helper pass two arguments: helper name and config values:

Scenario('should create data via v2 version of API', ({ I }) => {
+  // I.amOnPage(..)
+}).config('REST', { endpoint: 'https://api.mysite.com/v2' })
+

Config can also be set by a function, in this case you can get a test object and specify config values based on it. +This is very useful when running tests against cloud providers, like BrowserStack. This function can also be asynchronous.

Scenario('should report to BrowserStack', ({ I }) => {
+  // I.amOnPage(..)
+}).config((test) => {
+  return { desiredCapabilities: {
+    project: test.suite.title,
+    name: test.title,
+  }}
+});
+

Config changes can be applied to all tests in suite:

Feature('Admin Panel').config({ url: 'https://mysite.com/admin' });
+

Please note that some config changes can't be applied on the fly. For instance, if you set restart: false in your config and then changing value browser won't take an effect as browser is already started and won't be closed untill all tests finish.

Configuration changes will be reverted after a test or a suite.

Last Updated: 11/7/2023, 6:18:35 PM
+ + + diff --git a/ai/index.html b/ai/index.html new file mode 100644 index 00000000..42186c44 --- /dev/null +++ b/ai/index.html @@ -0,0 +1,269 @@ + + + + + + Testing with AI 🪄 | CodeceptJS + + + + + + + + + + + + + + + + +
Testing with AI 🪄

# 🪄 Testing with AI

CodeceptJS is the first open-source test automation framework with AI features to improve the testing experience. CodeceptJS uses AI provider like OpenAI or Anthropic to auto-heal failing tests, assist in writing tests, and more...

Think of it as your testing co-pilot built into the testing framework

🪄 AI features for testing are experimental. AI works only for web based testing with Playwright, WebDriver, etc. Those features will be improved based on user's experience.

# How AI Improves Automated Testing

LLMs like ChatGPT can technically write automated tests for you. However, ChatGPT misses the context of your application so it will guess elements on page, instead of writing the code that works.

CodeceptJS can share the testing context with AI provider when asked questions about a test.

So, instead of asking "write me a test" it can ask "write a test for this page". GPT knows how to write CodeceptJS code, how to build good-looking semantic locators and how to analyze HTML to match them. Even more, GPT suggestions can be tested in real-time in a browser, making a feedback loop.

CodeceptJS AI can do the following:

  • 🏋️‍♀️ assist writing tests in pause() or interactive shell mode
  • 📃 generate page objects in pause() or interactive shell mode
  • 🚑 self-heal failing tests (can be used on CI)
  • 💬 send arbitrary prompts to AI provider from any tested page attaching its HTML contents

# How it works

As we can't send a browser window with ChatGPT we are not be able to fully share the context. But we can chare HTML of the current page, which is quite enough to analyze and identify if a page contains an element which can be used in a test.

AI providers have limits on input tokens but HTML pages can be huge. However, some information from a web page may be irrelevant for testing. For instance, if you test a blog, you won't need text contents of a post, as it can't be used in locators. That's why CodeceptJS sends HTML with all non-interactive HTML elements removed. So, only links, buttons, fields, etc will be sent to AI as a context. In case you have clickable <div> but with no role="button" it will be ignored. Also, we minify HTML before sending.

Even though, the HTML is still quite big and may exceed the token limit. So we recommend using models with at least 16K input tokens, (approx. 50K of HTML text), which should be enough for most web pages. It is possible to strictly limit the size of HTML to not exceed tokens limit.

❗AI features require sending HTML contents to AI provider. Choosing one may depend on the descurity policy of your company. Ask your security department which AI providers you can use.

# Set up AI Provider

To enable AI features in CodeceptJS you should pick an AI provider and add ai section to codecept.conf file. This section should contain request function which will take a prompt from CodeceptJS, send it to AI provider and return a result.

ai: {
+  request: async (messages) => {
+    // implement OpenAI or any other provider like this
+    const ai = require('my-ai-provider')
+    return ai.send(messages);
+  }
+}
+

In request function messages is an array of prompt messages in format

[{ role: 'user', content: 'prompt text'}]
+

Which is natively supported by OpenAI, Anthropic, and others. You can adjust messages to expected format before sending a request. The expected response from AI provider is a text in markdown format with code samples, which can be interpreted by CodeceptJS.

Once AI provider is configured run tests with --ai flag to enable AI features

npx codeceptjs run --ai
+

Below we list sample configuration for popular AI providers

# OpenAI GPT

Prerequisite:

  • Install openai package
  • obtain OPENAI_API_KEY from OpenAI
  • set OPENAI_API_KEY as environment variable

Sample OpenAI configuration:

ai: {
+  request: async (messages) => {
+    const OpenAI = require('openai');
+    const openai = new OpenAI({ apiKey: process.env['OPENAI_API_KEY'] })
+
+    const completion = await openai.chat.completions.create({
+      model: 'gpt-3.5-turbo-0125',
+      messages,
+    });
+    
+    return completion?.choices[0]?.message?.content;
+  }
+}
+

# Mixtral

Mixtral is opensource and can be used via Cloudflare, Google Cloud, Azure or installed locally.

The simplest way to try Mixtral on your case is using Groq Cloud (opens new window) which provides Mixtral access with GPT-like API:

Prerequisite:

  • Install groq-sdk package
  • obtain GROQ_API_KEY from OpenAI
  • set GROQ_API_KEY as environment variable

Sample Groq configuration with Mixtral model:

ai: {
+  request: async (messages) => {
+    const chatCompletion = await groq.chat.completions.create({
+        messages,
+        model: "mixtral-8x7b-32768",
+    });
+    return chatCompletion.choices[0]?.message?.content || "";
+  }
+}
+

Groq also provides access to other opensource models like llama or gemma

# Anthropic Claude

Prerequisite:

  • Install @anthropic-ai/sdk package
  • obtain CLAUDE_API_KEY from Anthropic
  • set CLAUDE_API_KEY as environment variable
ai: {
+  request: async(messages) => {
+    const Anthropic = require('@anthropic-ai/sdk');
+
+    const anthropic = new Anthropic({
+      apiKey: process.env.CLAUDE_API_KEY,
+    });
+
+    const resp = await anthropic.messages.create({
+      model: 'claude-2.1',
+      max_tokens: 1024,
+      messages
+    });      
+    return resp.content.map((c) => c.text).join('\n\n');
+  }
+}
+

# Azure OpenAI

Prerequisite:

  • Install @azure/openai package
  • obtain Azure API key, resource name and deployment ID
ai: {
+  request: async(messages) => {
+    const { OpenAIClient, AzureKeyCredential } = require("@azure/openai");
+
+    const client = new OpenAIClient(
+      "https://<resource name>.openai.azure.com/", 
+      new AzureKeyCredential("<Azure API key>")
+    );
+    const { choices } = await client.getCompletions("<deployment ID>", messages);
+
+    return choices[0]?.message?.content;
+  }
+}
+

# Writing Tests with AI Copilot

If AI features are enabled when using interactive pause with pause() command inside tests:

For instance, let's create a test to try ai features via gt command:

npx codeceptjs gt
+

Name a test and write the code. We will use Scenario.only instead of Scenario to execute only this exact test.

Feature('ai');
+
+Scenario.only('test ai features', ({ I }) => {
+  I.amOnPage('https://getbootstrap.com/docs/5.1/examples/checkout/')
+  pause();
+});
+

Now run the test in debug mode with AI enabled:

npx codeceptjs run --debug --ai
+

When pause mode started you can ask GPT to fill in the fields on this page. Use natural language to describe your request, and provide enough details that AI could operate with it. It is important to include at least a space char in your input, otherwise, CodeceptJS will consider the input to be JavaScript code.

 I.fill checkout form with valid values without submitting it
+

GPT will generate code and data and CodeceptJS will try to execute its code. If it succeeds, the code will be saved to history and you will be able to copy it to your test.

This AI copilot works best with long static forms. In the case of complex and dynamic single-page applications, it may not perform as well, as the form may not be present on HTML page yet. For instance, interacting with calendars or inputs with real-time validations (like credit cards) can not yet be performed by AI.

Please keep in mind that GPT can't react to page changes and operates with static text only. This is why it is not ready yet to write the test completely. However, if you are new to CodeceptJS and automated testing AI copilot may help you write tests more efficiently.

👶 Enable AI copilot for junior test automation engineers. It may help them to get started with CodeceptJS and to write good semantic locators.

# Self-Healing Tests

In large test suites, the cost of maintaining tests goes exponentially. That's why any effort that can improve the stability of tests pays itself. That's why CodeceptJS has concept of heal recipes, functions that can be executed on a test failure. Those functions can try to revive the test and continue execution. When combined with AI, heal recipe can ask AI provider how to fix the test. It will provide error message, step being executed and HTML context of a page. Based on this information AI can suggest the code to be executed to fix the failing test.

AI healing can solve exactly one problem: if a locator of an element has changed, and an action can't be performed, it matches a new locator, tries a command again, and continues executing a test. For instance, if the "Sign in" button was renamed to "Login" or changed its class, it will detect a new locator of the button and will retry execution.

You can define your own heal recipes that won't use AI to revive failing tests.

Heal actions work only on actions like click, fillField, etc, and won't work on assertions, waiters, grabbers, etc. Assertions can't be guessed by AI, the same way as grabbers, as this may lead to unpredictable results.

If Heal plugin successfully fixes the step, it will print a suggested change at the end of execution. Take it as actionable advice and use it to update the codebase. Heal plugin is supposed to be used on CI, and works automatically without human assistance.

To start, make sure AI provider is connected, and heal recipes were created and included into codecept.conf.js or codecept.conf.ts config file. Then enable heal plugin:

plugins: {
+  heal: {
+    enabled: true
+  }
+}
+

If you tests in AI mode and test fails, a request to AI provider will be sent

npx codeceptjs run --ai
+

When execution finishes, you will receive information on token usage and code suggestions proposed by AI. +By evaluating this information you will be able to check how effective AI can be for your case.

# Arbitrary GPT Prompts

What if you want to take AI on the journey of test automation and ask it questions while browsing pages?

This is possible with the new AI helper. Enable it in your config file in helpers section:

// inside codecept.conf
+helpers: {
+  // Playwright, Puppeteer, or WebDrver helper should be enabled too
+  Playwright: {
+  },
+
+  AI: {}
+}
+

AI helper will be automatically attached to Playwright, WebDriver, or another web helper you use. It includes the following methods:

  • askGptOnPage - sends GPT prompt attaching the HTML of the page. Large pages will be split into chunks, according to chunkSize config. You will receive responses for all chunks.
  • askGptOnPageFragment - sends GPT prompt attaching the HTML of the specific element. This method is recommended over askGptOnPage as you can reduce the amount of data to be processed.
  • askGptGeneralPrompt - sends GPT prompt without HTML.
  • askForPageObject - creates PageObject for you, explained in next section.

askGpt methods won't remove non-interactive elements, so it is recommended to manually control the size of the sent HTML.

Here are some good use cases for this helper:

  • get page summaries
  • inside pause mode navigate through your application and ask to document pages
  • etc...
// use it inside test or inside interactive pause
+// pretend you are technical writer asking for documentation
+const pageDoc = await I.askGptOnPageFragment('Act as technical writer, describe what is this page for', '#container');
+

As of now, those use cases do not apply to test automation but maybe you can apply them to your testing setup.

# Generate PageObjects

Last but not the least. AI helper can be used to quickly prototype PageObjects on pages browsed within interactive session.

Enable AI helper as explained in previous section and launch shell:

npx codeceptjs shell --ai
+

Also this is availble from pause() if AI helper is enabled,

Ensure that browser is started in window mode, then browse the web pages on your site. +On a page you want to create PageObject execute askForPageObject() command. The only required parameter is the name of a page:

I.askForPageObject('login')
+

This command sends request to AI provider should create valid CodeceptJS PageObject. +Run it few times or switch AI provider if response is not satisfactory to you.

You can change the style of PageObject and locator preferences by adjusting prompt in a config file

When completed successfully, page object is saved to output directory and loaded into the shell as page variable so locators and methods can be checked on the fly.

If page object has signInButton locator you can quickly check it by typing:

I.click(page.signInButton)
+

If page object has clickForgotPassword method you can execute it as:

=> page.clickForgotPassword()
+
Page object for login is saved to .../output/loginPage-1718579784751.js
+Page object registered for this session as `page` variable
+Use `=>page.methodName()` in shell to run methods of page object
+Use `click(page.locatorName)` to check locators of page object
+
+ I.=>page.clickSignUp()
+ I.click(page.signUpLink)
+ I.=> page.enterPassword('asdasd')
+ I.=> page.clickSignIn()
+

You can improve prompt by passing custom request as a second parameter:

I.askForPageObject('login', 'implement signIn(username, password) method')
+

To generate page object for the part of a page, pass in root locator as third parameter.

I.askForPageObject('login', '', '#auth')
+

In this case, all generated locators, will use #auth as their root element.

Don't aim for perfect PageObjects but find a good enough one, which you can use for writing your tests. +All created page objects are considered temporary, that's why saved to output directory.

Rename created PageObject to remove timestamp and move it from output to pages folder and include it into codecept.conf file:

  include: {
+    loginPage: "./pages/loginPage.js",
+    // ...
+

# Advanced Configuration

GPT prompts and HTML compression can also be configured inside ai section of codecept.conf file:

ai: {
+  // define how requests to AI are sent 
+  request: (messages) => {
+    // ...
+  }
+  // redefine prompts 
+  prompts: {
+    // {}
+  },
+  // how to process HTML content
+  html: {
+    // {}
+  }
+  // limit the number of tokens to be
+  // used during one session
+  maxTokens: 100000
+}
+

Default prompts for healing steps or writing steps can be re-declared. Use function that accepts HTML as the first parameter and additional information as second and create a prompt from that information. Prompt should be an array of messages with role and content data set.

ai: {
+  prompts: {
+    writeStep: (html, input) => [{ role: 'user', content: 'As a test engineer...' }]
+    healStep: (html, { step, error, prevSteps }) => [{ role: 'user', content: 'As a test engineer...' }]
+    generatePageObject: (html, extraPrompt = '',  rootLocator = null) => [{ role: 'user', content: 'As a test engineer...' }]
+  }
+}
+

HTML is processed before sending it to GPT to reduce the number of tokens used. You may need to adjust default settings to work with your application. For instance, the default strategy may remove some important elements, or contrary keep HTML elements that have no use for test automation.

Here is the default config:

ai: {
+  html: {
+    maxLength: 50000,
+    simplify: true,
+    minify: true,
+    interactiveElements: ['a', 'input', 'button', 'select', 'textarea', 'option'],
+    textElements: ['label', 'h1', 'h2'],
+    allowedAttrs: ['id', 'for', 'class', 'name', 'type', 'value', 'tabindex', 'aria-labelledby', 'aria-label', 'label', 'placeholder', 'title', 'alt', 'src', 'role'],
+    allowedRoles: ['button', 'checkbox', 'search', 'textbox', 'tab'],
+  }
+}
+
  • maxLength: the size of HTML to cut to not reach the token limit. 50K is the current default but you may try to increase it or even set it to null.
  • simplify: should we process HTML before sending to GPT. This will remove all non-interactive elements from HTML.
  • minify: shold HTML be additionally minified. This removed empty attributes, shortens notations, etc.
  • interactiveElements: explicit list of all elements that are considered interactive.
  • textElements: elements that contain text which can be used for test automation.
  • allowedAttrs: explicit list of attributes that may be used to construct locators. If you use special data- attributes to enable locators, add them to the list.
  • allowedRoles: list of roles that make standard elements interactive.

It is recommended to try HTML processing on one of your web pages before launching AI features of CodeceptJS.

To do that open the common page of your application and using DevTools copy the outerHTML of <html> element. Don't use Page Source for that, as it may not include dynamically added HTML elements. Save this HTML into a file and create a NodeJS script:

const { removeNonInteractiveElements } = require('codeceptjs/lib/html');
+const fs = require('fs');
+
+const htmlOpts = {
+  interactiveElements: ['a', 'input', 'button', 'select', 'textarea', 'label', 'option'],
+  allowedAttrs: ['id', 'for', 'class', 'name', 'type', 'value', 'aria-labelledby', 'aria-label', 'label', 'placeholder', 'title', 'alt', 'src', 'role'],
+  textElements: ['label', 'h1', 'h2'],
+  allowedRoles: ['button', 'checkbox', 'search', 'textbox', 'tab'],
+};
+
+html = fs.readFileSync('saved.html', 'utf8');
+const result = removeNonInteractiveElements(html, htmlOpts);
+
+console.log(result);
+

Tune the options until you are satisfied with the results and use this as html config for ai section inside codecept.conf file. +It is also recommended to check the source of removeNonInteractiveElements (opens new window) and if needed propose improvements to it.

For instance, if you use data-qa attributes to specify locators and you want to include them in HTML, use the following config:

{
+  // inside codecept.conf.js
+  ai: {
+    html: {
+      allowedAttrs: [
+        'data-qa', 'id', 'for', 'class', 'name', 'type', 'value', 'aria-labelledby', 'aria-label', 'label', 'placeholder', 'title', 'alt', 'src', 'role'
+      ]
+    }
+  }
+}
+

# Debugging

To debug AI features run tests with DEBUG="codeceptjs:ai" flag. This will print all prompts and responses from AI provider

DEBUG="codeceptjs:ai" npx codeceptjs run --ai
+

or if you run it in shell mode:

DEBUG="codeceptjs:ai" npx codeceptjs shell --ai
+
Last Updated: 6/19/2024, 10:05:44 AM
+ + + diff --git a/angular/index.html b/angular/index.html new file mode 100644 index 00000000..48bd61d0 --- /dev/null +++ b/angular/index.html @@ -0,0 +1,257 @@ + + + + + + Testing with Protractor | CodeceptJS + + + + + + + + + + + + + + + + +
Testing with Protractor

# Protractor Testing with CodeceptJS

# Introduction

CodeceptJS is an acceptance testing framework. In the diversified world of JavaScript testing libraries, it aims to create a unified high-level API for end-to-end testing, powered by a variety of backends. +CodeceptJS allows you to write a test and switch the execution driver via config: whether it's wedriverio, puppeteer, or protractor depends on you. +This way you aren't bound to a specific implementation, and your acceptance tests will work no matter what framework is running them.

Protractor (opens new window) is an official tool for testing AngularJS applications. +CodeceptJS should not be considered as alternative to Protractor, but rather a testing framework that leverages this powerful library.

angular-protractor

There is no magic in testing of AngularJS application in CodeceptJS. +You just execute regular Protractor commands, packaged into a simple, high-level API.

todo-mvc

As an example, we will use the popular TodoMVC application (opens new window). +How would we test creating a new todo item using CodeceptJS?

Scenario('create todo item', ({ I }) => {
+  I.amOnPage('/');
+  I.dontSeeElement('#todo-count');
+  I.fillField({model: 'newTodo'}, 'Write a guide');
+  I.pressKey('Enter');
+  I.see('Write a guide', {repeater: "todo in todos"});
+  I.see('1 item left', '#todo-count');
+});
+

A similar test written using Protractor's native syntax (inherited from selenium-webdriver) would look like this:

it('should create todo item', (I) => {
+  browser.get("http://todomvc.com/examples/angularjs/#/");
+  expect(element(by.css("#todo-count")).isPresent()).toBeFalsy();
+  var inputField = element(by.model("newTodo"));
+  inputField.sendKeys("Write a guide");
+  inputField.sendKeys(protractor.Key.ENTER);
+  var todos = element.all(by.repeater("todo in todos"));
+  expect(todos.last().getText()).toEqual("Write a guide"));
+  element(by.css("#todo-count")).getText()).toContain('1 items left');
+});
+

Compared to the API proposed by CodeceptJS, the Protractor code looks more complicated. +Even more important, it's harder to read and follow the logic of the Protractor test. +Readability is a crucial part of acceptance testing. +Tests should be easy to modify when there are changes in the specification or design. +If the test is written in Protractor, it would likely require someone familiar with Protractor to make the change, whereas CodeceptJS allows anyone to understand and modify the test. +CodeceptJS provides scenario-driven approach, so a test is just a step-by-step representation of real user actions. +This means you can easily read and understand the steps in a test scenario, and edit the steps when the test needs to be changed.

In this way, CodeceptJS is similar to Cucumber. If you run a test with --steps option you will see this output:

TodoMvc --
+ create todo item
+ • I am on page "/"
+ • I dont see element "#todo-count"
+ • I fill field {"model":"newTodo"}, "Write a guide"
+ • I press key "Enter"
+ • I see "Write a guide", {"repeater":"todo in todos"}
+ • I see "1 item left", "#todo-count"
+ ✓ OK in 968ms
+

Unlike Cucumber, CodeceptJS is not about writing test scenarios to satisfy business rules or requirements. +Instead, its goal is to provide standard action steps you can use for testing applications. +Although it can't cover 100% of use cases, CodeceptJS aims for 90%. For the remainder, you can write your own steps inside a custom Helper (opens new window) using Protractor's API.

# Setting up CodeceptJS with Protractor

To start using CodeceptJS you will need to install it via NPM and initialize it in a directory with tests.

npm install codeceptjs --save
+npx codeceptjs init
+

You will be asked questions about the initial configuration, make sure you select the Protractor helper. +If your project didn't already have the Protractor library, it will be installed as part of this process. +Please agree to extend steps, and use http://todomvc.com/examples/angularjs/ as the url for Protractor helper.

For TodoMVC application, you will have following config created in the codecept.conf.js file:

exports.config = { tests: './*_test.js',
+  timeout: 10000,
+  output: './output',
+  helpers:
+   { Protractor:
+      { url: 'http://todomvc.com/examples/angularjs/',
+        driver: 'hosted',
+        browser: 'chrome',
+        rootElement: 'body' } },
+  include: { I: './steps_file.js' },
+  bootstrap: false,
+  mocha: {},
+  name: 'todoangular'
+}
+

Your first test can be generated with the gt command:

npx codeceptjs gt
+

After that, you can start writing your first CodeceptJS/Angular tests. +Please refer to the Protractor helper (opens new window) documentation for a list of all available actions. +You can also run the list command to see methods of I:

npx codeceptjs list
+

# Starting Selenium Server

Protractor requires Selenium Server to be started and running. To start and stop Selenium automatically install @wdio/selenium-standalone-service.

npm i @wdio/selenium-standalone-service --save
+

Enable it in the codecept.conf.js file, inside the plugins section:

exports.config = {
+  // ...
+  // inside codecept.conf.js
+  plugins: {
+    wdio: {
+        enabled: true,
+        services: ['selenium-standalone']
+    }
+  }
+}
+

# Testing non-Angular Applications

Protractor can also be used to test applications built without AngularJS. In this case, you need to disable the angular synchronization feature inside the config:

helpers: {
+  Protractor: {
+    url: "http://todomvc.com/examples/angularjs/",
+    driver: "hosted",
+    browser: "firefox",
+    angular: false
+  }
+}
+

# Writing Your First Test

Your test scenario should always use the I object to execute commands. +This is important, as all methods of I are running in the global promise chain. This way, CodeceptJS makes sure everything is executed in right order. +To start with opening a webpage, use the amOnPage command for. Since we already specified the full URL to the TodoMVC app, we can pass the relative path for our url, instead of the absolute url:

Feature('Todo MVC');
+
+Scenario('create todo item', ({ I }) => {
+  I.amOnPage('/');
+});
+

All scenarios should describe actions on the site, with assertions at the end. In CodeceptJS, assertion commands have the see or dontSee prefix:

Feature('Todo MVC');
+
+Scenario('create todo item', ({ I }) => {
+  I.amOnPage('/');
+  I.dontSeeElement('#todo-count');
+});
+

A test can be executed with the run command, we recommend using the --steps option to print out the step-by-step execution:

npx codeceptjs run --steps
+
Test root is assumed to be /home/davert/demos/todoangular
+Using the selenium server at http://localhost:4444/wd/hub
+
+TodoMvc --
+ create todo item
+ • I am on page "/"
+ • I dont see element "#todo-count"
+

# Running Several Scenarios

By now, you should have a test similar to the one shown in the beginning of this guide. We probably want to have multiple tests though, like testing the editing of todo items, checking todo items, etc.

Let's prepare our test to contain multiple scenarios. All of our test scenarios will need to to start with with the main page of application open, so amOnPage can be moved into the Before hook: +Our scenarios will also probably deal with created todo items, so we can move the logic of creating a new todo into a function.

Feature('TodoMvc');
+
+Before(({ I }) => {
+  I.amOnPage('/');
+});
+
+const createTodo = function (I, name) {
+  I.fillField({model: 'newTodo'}, name);
+  I.pressKey('Enter');
+}
+
+Scenario('create todo item', ({ I }) => {
+  I.dontSeeElement('#todo-count');
+  createTodo(I, 'Write a guide');
+  I.see('Write a guide', {repeater: "todo in todos"});
+  I.see('1 item left', '#todo-count');
+});
+

and now we can add even more tests!

Scenario('edit todo', ({ I }) => {
+  createTodo(I, 'write a review');
+  I.see('write a review', {repeater: "todo in todos"});
+  I.doubleClick('write a review');
+  I.pressKey(['Control', 'a']);
+  I.pressKey('write old review');
+  I.pressKey('Enter');
+  I.see('write old review', {repeater: "todo in todos"});
+});
+
+Scenario('check todo item', ({ I }) => {
+  createTodo(I, 'my new item');
+  I.see('1 item left', '#todo-count');
+  I.checkOption({model: 'todo.completed'});
+  I.see('0 items left', '#todo-count');
+});
+

This example is available on GitHub (opens new window).

# Locators

You may have noticed that CodeceptJS doesn't use by.* locators which are common in Protractor or Selenium Webdriver. +Instead, most methods expect you to pass valid CSS selectors or XPath. If you don't want CodeceptJS to guess the locator type, then you can specify the type using strict locators. This is the CodeceptJS version of by, so you can also reuse your angular specific locators (like models, repeaters, bindings, etc):

{css: 'button'}
+{repeater: "todo in todos"}
+{binding: 'latest'}
+

When dealing with clicks, we can specify a text value. CodeceptJS will use that value to search the web page for a valid clickable element containing our specified text. +This enables us to search for links and buttons by their text.

The same is true for form fields: they can be searched by field name, label, and so on.

Using smart locators makes tests easier to write, however searching an element by text is slower than searching via CSS|XPath, and is much slower than using strict locators.

# Refactoring

In the previous examples, we moved actions into the createTodo function. Is there a more elegant way of refactoring? +Can we instead write a function like I.createTodo() which we can reuse? In fact, we can do so by editing the steps_file.js file created by the init command.

// in this file you can append custom step methods to 'I' object
+
+module.exports = function() {
+  return actor({
+    createTodo: function(title) {
+      this.fillField({model: 'newTodo'}, title);
+      this.pressKey('Enter');
+    }
+  });
+}
+

That's it, our method is now available to use as I.createTodo(title):

Scenario('create todo item', ({ I }) => {
+  I.dontSeeElement('#todo-count');
+  I.createTodo('Write a guide');
+  I.see('Write a guide', {repeater: "todo in todos"});
+  I.see('1 item left', '#todo-count');
+});
+

To learn more about refactoring options in CodeceptJS read PageObjects guide (opens new window).

# Extending

What if CodeceptJS doesn't provide some specific Protractor functionality you need? If you don't know how to do something with CodeceptJS, you can simply revert back to using Protractor syntax!

Create a custom helper, define methods for it, and use it inside the I object. Your Helper can access browser from Protractor +by accessing the Protractor helper:

let browser = this.helpers['Protractor'].browser;
+

or use global element and by variables to locate elements:

element.all(by.repeater('result in memory'));
+

This is the recommended way to implement all custom logic using low-level Protractor syntax in order to reuse it inside of test scenarios. +For more information, see an example of such a helper (opens new window).

Last Updated: 10/21/2020, 3:19:08 AM
+ + + diff --git a/api/index.html b/api/index.html new file mode 100644 index 00000000..cd918ca9 --- /dev/null +++ b/api/index.html @@ -0,0 +1,263 @@ + + + + + + API Testing | CodeceptJS + + + + + + + + + + + + + + + + +
API Testing

# API Testing

CodeceptJS provides a way to write tests in declarative manner for REST and GraphQL APIs.

Take a look:

I.sendGetRequest('/users/1');
+// returns { "user": { "name": "jon" }, "projects": [] }
+I.seeResponseCodeIsSuccessful();
+I.seeResponseContainsKeys(['user', 'projects']);
+I.seeResponseContainsJson({ user: { name: 'jon' } });
+I.seeResponseMatchesJsonSchema($ => {
+  return $.object(
+    user: $.object({
+      name: $.string(),
+    }),
+    projects: $.array()
+  )
+});
+

In this code we checked API request for:

  • status code
  • data inclusion
  • data structure

These are the things you should generally test your APIs for.

🤓 It is recommended to check only invariable parts of responses. Check for required fields and only values you control. For instance, it is not recommended to check id fields, date fields, as they can be frequently changed.

# Installation

Install CodeceptJS if it is not installed yet.

npm i codeceptjs --save-dev
+

Initialize CodeceptJS and select REST or GraphQL helper when asked for a helper:

npx codeceptjs init
+

# Configuration

Ensure that inside codecept.conf.js in helpers section REST or GraphQL helpers are enabled.

  • If you use REST helper add JSONResponse helper below with no extra config:
// inside codecept.conf.js
+// ...
+  helpers: {
+    REST: {
+      endpoint: 'http://localhost:3000/api'
+    },
+    // .. add JSONResponse helper here
+    JSONResponse: {}
+  }
+
  • If you use GraphQL helper add JSONResponse helper, configuring it to use GraphQL for requests:
  helpers: {
+    GraphQL: {
+      endpoint: 'http://localhost:3000/graphql'
+    },
+    // .. add JSONResponse helper here
+    JSONResponse: {
+      requestHelper: 'GraphQL',
+    }
+  }
+

Originally, REST and GraphQL helpers were not designed for API testing. +They were used to perform API requests for browser tests. As so, they lack assertion methods to API responses.

JSONResponse helper adds response assertions.

💡 In CodeceptJS assertions start with see prefix. Learn more about assertions by opening reference for JSONResponse helper.

Generate TypeScript definitions to get auto-completions for JSONResponse:

npx codeceptjs def
+

After helpers were configured and typings were generated, you can start writing first API test. By default, CodeceptJS saves tests in tests directory and uses *_test.js suffix. The init command created the first test for you to start.

Check API Examples (opens new window) to see tests implementations.

# Requests

REST or GraphQL helpers implement methods for making API requests. +Both helpers send requests via HTTP protocol from CodeceptJS process. +For most cases, you will need to have authentication. It can be passed via headers, which can be added to helper's configuration in codecept.conf.js.

helpers: {
+  REST: {
+    defaultHeaders: {
+      // use Bearer Authorization
+      'Authorization': 'Bearer 11111',
+      'Content-Type': 'application/json',
+      'Accept': 'application/json',
+    },
+  }
+}
+

Or you can use the browser cookies if you are running browser session. +In this case use setSharedCookies() from @codeceptjs/configure package:

const { setSharedCookies } = require('@codeceptjs/configure');
+
+// add this before exports.config
+setSharedCookies();
+
+exports.config = {
+  // ...
+  helpers: {  
+    // also works with Playwright or Puppeteer
+    WebDriver: {
+      //... 
+    },
+
+    REST: { 
+      // ...
+    }
+  }
+}
+

# REST

REST helper can send GET/POST/PATCH/etc requests to REST API endpoint:

Authentication headers can be set in helper's config (opens new window) or per test with headers or special methods like I.amBearerAuthenticated.

Example:

Feature('Users endpoint')
+
+Scenario('create user', ({ I }) => {
+    // this way we pass Bearer token
+  I.amBearerAuthenticated(secret('token-is-here'));
+  // for custom authorization with headers use
+  // I.haveRequestHeaders method
+
+  // here we send a POST request
+  const response = await I.sendPostRequest('/users', {
+    name: 'joe',
+    email: 'joe@mail.com'
+  });
+  // usually we won't need direct access to response object for API testing 
+  // but you can obtain it from request
+
+  // check the last request was successful
+  // this method introduced by JSONResponse helper
+  I.seeResponseCodeIsSuccessful();
+})
+

# GraphQL

GraphQL have request format different then in REST API, but the response format is the same. +It's plain old JSON. This why JSONResponse helper works for both API types. +Configure authorization headers in codecept.conf.js and make your first query:

Feature('Users endpoint')
+
+Scenario('get user by query', ({ I }) => {
+  // make GraphQL query or mutation
+  const resp = await I.sendQuery('{ user(id: 0) { id name email }}');
+  I.seeResponseCodeIsSuccessful();
+
+  // GraphQL always returns key data as part of response
+  I.seeResponseContainsKeys(['data']);
+
+  // check data for partial inclusion
+  I.seeResponseContainsJson({
+    data: {
+      user: {
+        name: 'john doe',
+        email: 'johnd@mutex.com',
+      },
+    },
+  });
+});
+

GraphQL helper has two methods available:

# Assertions

JSONResponse provides set of assertions for responses in JSON format. These assertions were designed to check only invariable parts of responses. So instead of checking that response equals to the one provided, we will check for data inclusion and structure matching.

For most of cases, you won't need to perform assertions by accessing response object directly. All assretions are performed under hood inside JSONResponse module. It is recommended to keep it that way, to keep tests readable and make test log to contain all assertions.

Scenario('I make API call', ({ I }) => {
+  // request was made by REST 
+  // or by GraphQL helper
+
+  // check that response code is 2xx
+  I.seeResponseCodeIsSuccessful();
+
+  // check that response contains keys
+  I.seeResponseContainsKeys(['data', 'pages', 'meta']);
+});
+

# Response Status Codes

Response status codes (opens new window) can be checked to be equal to some value or to be in a specific range. +To check that response code is 200 call I.seeResponseCodeIs:

I.seeResponseCodeIs(200);
+

But because other response codes in 2xx range are also valid responses, you can use seeResponseCodeIsSuccessful() which will match 200 (OK), 201 (Created), 206 (Partial Content) and others. Methods to check 3xx, 4xx, 5xx response statuses also available.

// matches 200, 201, 202, ... 206
+I.seeResponseCodeIsSuccessful();
+
+// matches 300...308
+I.seeResponseCodeIsRedirection();
+
+// matches 400..451
+I.seeResponseCodeIsClientError();
+
+// matches 500-511
+I.seeResponseCodeIsServerError();
+

# Structure

The most basic thing to check in response is existence of keys in JSON object. Use I.seeResponseContainsKeys() method for it:

// response is { "name": "joe", "email": "joe@joe.com" }
+I.seeResponseContainsKeys(['name', 'email']);
+

ℹ️ If response is an array, it will check that every element in array have provided keys

However, this is a very naive approach. It won't work for arrays or nested objects. +To check complex JSON structures JSONResponse helper uses joi (opens new window) library. +It has rich API to validate JSON by the schema defined using JavaScript.

// require joi library, 
+// it is installed with CodeceptJS
+const Joi = require('joi');
+
+// create schema definition using Joi API
+const schema = Joi.object().keys({
+  email: Joi.string().email().required(),
+  phone: Joi.string().regex(/^\d{3}-\d{3}-\d{4}$/).required(),
+  birthday: Joi.date().max('1-1-2004').iso()
+});
+
+// check that response matches that schema
+I.seeResponseMatchesJsonSchema(schema);
+

# Data Inclusion

To check that response contains expected data use I.seeResponseContainsJson method. +It will check the response data for partial match.

I.seeResponseContainsJson({
+  user: {
+    email: 'user@user.com'
+  }
+})
+

ℹ️ If response is an array, it will check that at least one element in array matches JSON

To perform arbitrary assertions on a response object use seeResponseValidByCallback. +It allows you to do any kind of assertions by using expect from chai (opens new window) library.

I.seeResponseValidByCallback(({ data, status, expect }) => {
+  // we receive data and expect to combine them for good assertion
+  expect(data.users.length).to.be.gte(10);
+})
+

# Extending JSONResponse

To add more assertions it is recommended to create a custom helper. +Inside it you can get access to latest JSON response:

// inside a custom helper
+makeSomeCustomAssertion() {
+  const response = this.helpers.JSONResponse.response;
+}
+
Last Updated: 7/12/2022, 12:16:43 AM
+ + + diff --git a/assets/css/0.styles.1a6b889a.css b/assets/css/0.styles.1a6b889a.css new file mode 100644 index 00000000..5cc0468a --- /dev/null +++ b/assets/css/0.styles.1a6b889a.css @@ -0,0 +1 @@ +@import url(https://fonts.googleapis.com/css?family=IBM+Plex+Sans);@import url(https://fonts.googleapis.com/css?family=IBM+Plex+Mono);.theme-default-content code{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity));--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity));padding:.25rem .5rem;margin:0;border-radius:3px}.theme-default-content code .token.deleted{color:#ec5975}.theme-default-content code .token.inserted{color:#805ad5}.theme-default-content pre,.theme-default-content pre[class*=language-]{padding:1rem 1.5rem;margin:.85rem 0;font-size:1.25rem;line-height:1.375;border-radius:6px;overflow:auto;background:#404040}@media (max-width:419px){.theme-default-content pre,.theme-default-content pre[class*=language-]{padding:1rem}}.theme-default-content pre[class*=language-] code,.theme-default-content pre code{color:#fff;padding:0;background-color:transparent;border-radius:0}div[class*=language-]{position:relative;background-color:#282c34;border-radius:6px}div[class*=language-] .highlight-lines{user-select:none;padding-top:1.3rem;position:absolute;top:0;left:0;width:100%;line-height:1.4}div[class*=language-] .highlight-lines .highlighted{background-color:rgba(0,0,0,.66)}div[class*=language-] pre,div[class*=language-] pre[class*=language-]{background:transparent;position:relative;z-index:1}div[class*=language-]:before{position:absolute;z-index:3;top:.8em;right:1em;font-size:.75rem;color:hsla(0,0%,100%,.4)}div[class*=language-]:not(.line-numbers-mode) .line-numbers-wrapper{display:none}div[class*=language-].line-numbers-mode .highlight-lines .highlighted{position:relative}div[class*=language-].line-numbers-mode .highlight-lines .highlighted:before{content:" ";position:absolute;z-index:3;left:0;top:0;display:block;width:3.5rem;height:100%;background-color:rgba(0,0,0,.66)}div[class*=language-].line-numbers-mode pre{padding-left:4.5rem;vertical-align:middle}div[class*=language-].line-numbers-mode .line-numbers-wrapper{position:absolute;top:0;width:3.5rem;text-align:center;color:hsla(0,0%,100%,.3);padding:1.25rem 0;line-height:1.4}div[class*=language-].line-numbers-mode .line-numbers-wrapper br{user-select:none}div[class*=language-].line-numbers-mode .line-numbers-wrapper .line-number{position:relative;z-index:4;user-select:none;font-size:.85em}div[class*=language-].line-numbers-mode:after{content:"";position:absolute;z-index:2;top:0;left:0;width:3.5rem;height:100%;border-radius:6px 0 0 6px;border-right:1px solid rgba(0,0,0,.66)}div[class~=language-js]:before{content:"js"}div[class~=language-ts]:before{content:"ts"}div[class~=language-html]:before{content:"html"}div[class~=language-md]:before{content:"md"}div[class~=language-vue]:before{content:"vue"}div[class~=language-css]:before{content:"css"}div[class~=language-sass]:before{content:"sass"}div[class~=language-scss]:before{content:"scss"}div[class~=language-less]:before{content:"less"}div[class~=language-stylus]:before{content:"stylus"}div[class~=language-go]:before{content:"go"}div[class~=language-java]:before{content:"java"}div[class~=language-c]:before{content:"c"}div[class~=language-sh]:before{content:"sh"}div[class~=language-yaml]:before{content:"yaml"}div[class~=language-py]:before{content:"py"}div[class~=language-docker]:before{content:"docker"}div[class~=language-dockerfile]:before{content:"dockerfile"}div[class~=language-makefile]:before{content:"makefile"}div[class~=language-javascript]:before{content:"js"}div[class~=language-typescript]:before{content:"ts"}div[class~=language-markup]:before{content:"html"}div[class~=language-markdown]:before{content:"md"}div[class~=language-json]:before{content:"json"}div[class~=language-ruby]:before{content:"rb"}div[class~=language-python]:before{content:"py"}div[class~=language-bash]:before{content:"sh"}div[class~=language-php]:before{content:"php"}.custom-block .custom-block-title{font-weight:600;margin-bottom:-.4rem}.custom-block.danger,.custom-block.tip,.custom-block.warning{padding:.1rem 1.5rem;border-left-width:.5rem;border-left-style:solid;margin:1rem 0}.custom-block.tip{background-color:#f3f5f7;border-color:#42b983}.custom-block.warning{background-color:rgba(255,229,100,.3);border-color:#e7c000;color:#6b5900}.custom-block.warning .custom-block-title{color:#b29400}.custom-block.warning a{color:#2c3e50}.custom-block.danger{background-color:#ffe6e6;border-color:#c00;color:#4d0000}.custom-block.danger .custom-block-title{color:#900}.custom-block.danger a{color:#2c3e50}.arrow{display:inline-block;width:0;height:0}.arrow.up{border-bottom:6px solid #ccc}.arrow.down,.arrow.up{border-left:4px solid transparent;border-right:4px solid transparent}.arrow.down{border-top:6px solid #ccc}.arrow.right{border-left:6px solid #ccc}.arrow.left,.arrow.right{border-top:4px solid transparent;border-bottom:4px solid transparent}.arrow.left{border-right:6px solid #ccc}.theme-default-content:not(.custom){max-width:760px;margin:1rem auto;padding:2rem 1rem}@media (max-width:959px){.theme-default-content:not(.custom){padding:2rem}}@media (max-width:419px){.theme-default-content:not(.custom){padding:1.5rem 1rem}.theme-default-content:not(.custom) li,.theme-default-content:not(.custom) p{word-break:break-word}}.table-of-contents .badge{vertical-align:middle}body,html{padding:0;margin:0;background-color:#fff}body{font-family:IBM Plex Sans,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;font-size:16px;color:#2c3e50}.page{padding-left:20rem}@media (min-width:1401px){.page{padding-right:20rem}}.navbar{z-index:20;right:0;height:3.6rem;box-sizing:border-box}.navbar,.sidebar-mask{position:fixed;top:0;left:0}.sidebar-mask{z-index:9;width:100vw;height:100vh;display:none}.small{font-size:.875rem}.content a{text-decoration:underline}a.button{padding:.5rem 1rem;--bg-opacity:1;background-color:#dd6b20;background-color:rgba(221,107,32,var(--bg-opacity));--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}a.button.extended{display:block;text-align:center}a.button.green{background-color:#38a169;background-color:rgba(56,161,105,var(--bg-opacity));display:inline-block}a.button.green,a.button.red{--bg-opacity:1;--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity))}a.button.red{background-color:#e53e3e;background-color:rgba(229,62,62,var(--bg-opacity))}.sidebar{font-size:16px;width:20rem;position:fixed;z-index:10;margin:0;top:7.2rem;left:0;bottom:0;box-sizing:border-box;border-right:1px solid #eaecef;overflow-y:auto}.theme-default-content:not(.custom)>:first-child{margin-top:3.6rem}.theme-default-content:not(.custom) a:hover{text-decoration:underline}.theme-default-content:not(.custom) p.demo{padding:1rem 1.5rem;border:1px solid #ddd;border-radius:4px}.theme-default-content:not(.custom) img{max-width:100%}.theme-default-content:not(.custom) a{word-break:break-word;text-decoration:underline}.theme-default-content:not(.custom) ol a,.theme-default-content:not(.custom) ul a{text-decoration:none}.theme-default-content.custom{padding:0;margin:0}.theme-default-content.custom img{max-width:100%}a{font-weight:500;--text-opacity:1;color:#2c5282;color:rgba(44,82,130,var(--text-opacity));text-decoration:none}p a code{font-weight:400;color:#805ad5}kbd{background:#eee;border:.15rem solid #ddd;border-bottom:.25rem solid #ddd;border-radius:.15rem;padding:0 .15em}blockquote{font-size:1rem;border-left:.4rem solid #dfe2e5;margin:1rem 0;padding:1rem 1.5rem;--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity));border-radius:.5rem;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06);--bg-opacity:1;background-color:#fefcbf;background-color:rgba(254,252,191,var(--bg-opacity))}blockquote>p{margin:0}ol,ul{padding-left:1.2em}strong{font-weight:600}h1,h2,h3,h4,h5,h6{font-weight:600;line-height:1.25}.theme-default-content:not(.custom)>h1,.theme-default-content:not(.custom)>h2,.theme-default-content:not(.custom)>h3,.theme-default-content:not(.custom)>h4,.theme-default-content:not(.custom)>h5,.theme-default-content:not(.custom)>h6{margin-top:-6.6rem;padding-top:8.6rem;margin-bottom:0}.theme-default-content:not(.custom)>h1:first-child,.theme-default-content:not(.custom)>h2:first-child,.theme-default-content:not(.custom)>h3:first-child,.theme-default-content:not(.custom)>h4:first-child,.theme-default-content:not(.custom)>h5:first-child,.theme-default-content:not(.custom)>h6:first-child{margin-top:-4.5rem;margin-bottom:1rem}.theme-default-content:not(.custom)>h1:first-child+.custom-block,.theme-default-content:not(.custom)>h1:first-child+p,.theme-default-content:not(.custom)>h1:first-child+pre,.theme-default-content:not(.custom)>h2:first-child+.custom-block,.theme-default-content:not(.custom)>h2:first-child+p,.theme-default-content:not(.custom)>h2:first-child+pre,.theme-default-content:not(.custom)>h3:first-child+.custom-block,.theme-default-content:not(.custom)>h3:first-child+p,.theme-default-content:not(.custom)>h3:first-child+pre,.theme-default-content:not(.custom)>h4:first-child+.custom-block,.theme-default-content:not(.custom)>h4:first-child+p,.theme-default-content:not(.custom)>h4:first-child+pre,.theme-default-content:not(.custom)>h5:first-child+.custom-block,.theme-default-content:not(.custom)>h5:first-child+p,.theme-default-content:not(.custom)>h5:first-child+pre,.theme-default-content:not(.custom)>h6:first-child+.custom-block,.theme-default-content:not(.custom)>h6:first-child+p,.theme-default-content:not(.custom)>h6:first-child+pre{margin-top:2rem}.content__default>h1,.content__default>h2,.content__default>h3,.content__default>h4,.content__default>h5,.content__default>h6{margin-top:-6.6rem;padding-top:8.6rem;margin-bottom:0}.content__default>h1:first-child,.content__default>h2:first-child,.content__default>h3:first-child,.content__default>h4:first-child,.content__default>h5:first-child,.content__default>h6:first-child{margin-top:-8.6rem;margin-bottom:1rem}h1:hover .header-anchor,h2:hover .header-anchor,h3:hover .header-anchor,h4:hover .header-anchor,h5:hover .header-anchor,h6:hover .header-anchor{opacity:1}h1{font-size:2.2rem}h2{font-size:1.65rem;padding-bottom:.3rem;border-bottom:1px solid #eaecef}h3{font-size:1.35rem}a.header-anchor{font-size:.85em;float:left;margin-left:-.87em;padding-right:.23em;margin-top:.125em;opacity:0}a.header-anchor:hover{text-decoration:none!important}.line-number,code,kbd{font-family:IBM Plex Mono,source-code-pro,Menlo,Monaco,Consolas,Courier New,monospace;font-size:.875rem}ol,p,ul{line-height:1.7}hr{border:0;border-top:1px solid #eaecef}table{border-collapse:collapse;margin:1rem 0;display:block;overflow-x:auto}tr{border-top:1px solid #dfe2e5}tr:nth-child(2n){background-color:#f6f8fa}td,th{border:1px solid #dfe2e5;padding:.6em 1em}.theme-container.sidebar-open .sidebar-mask{display:block;background-color:#000;opacity:.7}.theme-container.no-navbar .theme-default-content:not(.custom)>h1,.theme-container.no-navbar h2,.theme-container.no-navbar h3,.theme-container.no-navbar h4,.theme-container.no-navbar h5,.theme-container.no-navbar h6{margin-top:1.5rem;padding-top:0}.theme-container.no-navbar .sidebar{top:0}#quickstart{margin-top:-8.6rem}.theme-container.no-sidebar .content a{text-decoration:underline}@media (min-width:720px){.theme-container.no-sidebar .page{padding-left:0;padding-right:0}}@media (min-width:1150px){.theme-container.no-sidebar .sidebar{display:none}}@media (max-width:719px){.links .search-box input{left:0}}@media (max-width:959px){.sidebar{font-size:15px;width:16.4rem}.page{padding-left:16.4rem}}@media (max-width:1150px){.sidebar{top:0;padding-top:3.6rem;transform:translateX(-100%);transition:transform .2s ease}.page{padding-left:0}.theme-container.sidebar-open .sidebar{transform:translateX(0)}.theme-container.no-navbar .sidebar{padding-top:0}}@media (max-width:419px){h1{font-size:1.9rem}.theme-default-content div[class*=language-]{margin:.85rem -1rem;border-radius:0}}#nprogress{pointer-events:none}#nprogress .bar{background:#553c9a;position:fixed;z-index:1031;top:0;left:0;width:100%;height:2px}#nprogress .peg{display:block;position:absolute;right:0;width:100px;height:100%;box-shadow:0 0 10px #553c9a,0 0 5px #553c9a;opacity:1;transform:rotate(3deg) translateY(-4px)}#nprogress .spinner{display:block;position:fixed;z-index:1031;top:15px;right:15px}#nprogress .spinner-icon{width:18px;height:18px;box-sizing:border-box;border-color:#553c9a transparent transparent #553c9a;border-style:solid;border-width:2px;border-radius:50%;animation:nprogress-spinner .4s linear infinite}.nprogress-custom-parent{overflow:hidden;position:relative}.nprogress-custom-parent #nprogress .bar,.nprogress-custom-parent #nprogress .spinner{position:absolute}@-moz-keyframes nprogress-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@-webkit-keyframes nprogress-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@-o-keyframes nprogress-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}@keyframes nprogress-spinner{0%{transform:rotate(0deg)}to{transform:rotate(1turn)}}.icon.outbound{color:#aaa;display:inline-block;vertical-align:middle;position:relative;top:-1px}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border-width:0}.badge[data-v-76652c5d]{display:inline-block;font-size:14px;height:18px;line-height:18px;border-radius:3px;padding:0 6px;color:#fff}.badge.green[data-v-76652c5d],.badge.tip[data-v-76652c5d],.badge[data-v-76652c5d]{background-color:#42b983}.badge.error[data-v-76652c5d]{background-color:#da5961}.badge.warn[data-v-76652c5d],.badge.warning[data-v-76652c5d],.badge.yellow[data-v-76652c5d]{background-color:#e7c000}.badge+.badge[data-v-76652c5d]{margin-left:5px}.searchbox{display:inline-block;position:relative;width:200px;height:32px!important;white-space:nowrap;box-sizing:border-box;visibility:visible!important}.searchbox .algolia-autocomplete{display:block;width:100%;height:100%}.searchbox__wrapper{width:100%;height:100%;z-index:999;position:relative}.searchbox__input{display:inline-block;box-sizing:border-box;transition:box-shadow .4s ease,background .4s ease;border:0;border-radius:16px;box-shadow:inset 0 0 0 1px #ccc;background:#fff!important;padding:0 26px 0 32px;width:100%;height:100%;vertical-align:middle;white-space:normal;font-size:12px;-webkit-appearance:none;-moz-appearance:none;appearance:none}.searchbox__input::-webkit-search-cancel-button,.searchbox__input::-webkit-search-decoration,.searchbox__input::-webkit-search-results-button,.searchbox__input::-webkit-search-results-decoration{display:none}.searchbox__input:hover{box-shadow:inset 0 0 0 1px #b3b3b3}.searchbox__input:active,.searchbox__input:focus{outline:0;box-shadow:inset 0 0 0 1px #aaa;background:#fff}.searchbox__input::-webkit-input-placeholder{color:#aaa}.searchbox__input:-ms-input-placeholder{color:#aaa}.searchbox__input::-ms-input-placeholder{color:#aaa}.searchbox__input::placeholder{color:#aaa}.searchbox__submit{position:absolute;top:0;margin:0;border:0;border-radius:16px 0 0 16px;background-color:rgba(69,142,225,0);padding:0;width:32px;height:100%;vertical-align:middle;text-align:center;font-size:inherit;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;right:inherit;left:0}.searchbox__submit:before{display:inline-block;margin-right:-4px;height:100%;vertical-align:middle;content:""}.searchbox__submit:active,.searchbox__submit:hover{cursor:pointer}.searchbox__submit:focus{outline:0}.searchbox__submit svg{width:14px;height:14px;vertical-align:middle;fill:#6d7e96}.searchbox__reset{display:block;position:absolute;top:8px;right:8px;margin:0;border:0;background:none;cursor:pointer;padding:0;font-size:inherit;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;fill:rgba(0,0,0,.5)}.searchbox__reset.hide{display:none}.searchbox__reset:focus{outline:0}.searchbox__reset svg{display:block;margin:4px;width:8px;height:8px}.searchbox__input:valid~.searchbox__reset{display:block;-webkit-animation-name:sbx-reset-in;animation-name:sbx-reset-in;-webkit-animation-duration:.15s;animation-duration:.15s}@-webkit-keyframes sbx-reset-in{0%{-webkit-transform:translate3d(-20%,0,0);transform:translate3d(-20%,0,0);opacity:0}to{-webkit-transform:none;transform:none;opacity:1}}@keyframes sbx-reset-in{0%{-webkit-transform:translate3d(-20%,0,0);transform:translate3d(-20%,0,0);opacity:0}to{-webkit-transform:none;transform:none;opacity:1}}.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu{right:0!important;left:inherit!important}.algolia-autocomplete.algolia-autocomplete-right .ds-dropdown-menu:before{right:48px}.algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu{left:0!important;right:inherit!important}.algolia-autocomplete.algolia-autocomplete-left .ds-dropdown-menu:before{left:48px}.algolia-autocomplete .ds-dropdown-menu{top:-6px;border-radius:4px;margin:6px 0 0;padding:0;text-align:left;height:auto;position:relative;background:transparent;border:none;z-index:999;max-width:600px;min-width:500px;box-shadow:0 1px 0 0 rgba(0,0,0,.2),0 2px 3px 0 rgba(0,0,0,.1)}.algolia-autocomplete .ds-dropdown-menu:before{display:block;position:absolute;content:"";width:14px;height:14px;background:#fff;z-index:1000;top:-7px;border-top:1px solid #d9d9d9;border-right:1px solid #d9d9d9;-webkit-transform:rotate(-45deg);transform:rotate(-45deg);border-radius:2px}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions{position:relative;z-index:1000;margin-top:8px}.algolia-autocomplete .ds-dropdown-menu .ds-suggestions a:hover{text-decoration:none}.algolia-autocomplete .ds-dropdown-menu .ds-suggestion{cursor:pointer}.algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion.suggestion-layout-simple,.algolia-autocomplete .ds-dropdown-menu .ds-suggestion.ds-cursor .algolia-docsearch-suggestion:not(.suggestion-layout-simple) .algolia-docsearch-suggestion--content{background-color:rgba(69,142,225,.05)}.algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-]{position:relative;border:1px solid #d9d9d9;background:#fff;border-radius:4px;overflow:auto;padding:0 8px 8px}.algolia-autocomplete .ds-dropdown-menu *{box-sizing:border-box}.algolia-autocomplete .algolia-docsearch-suggestion{display:block;position:relative;padding:0 8px;background:#fff;color:#02060c;overflow:hidden}.algolia-autocomplete .algolia-docsearch-suggestion--highlight{color:#174d8c;background:rgba(143,187,237,.1);padding:.1em .05em}.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl0 .algolia-docsearch-suggestion--highlight,.algolia-autocomplete .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--category-header-lvl1 .algolia-docsearch-suggestion--highlight,.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{padding:0 0 1px;background:inherit;box-shadow:inset 0 -2px 0 0 rgba(69,142,225,.8);color:inherit}.algolia-autocomplete .algolia-docsearch-suggestion--content{display:block;float:right;width:70%;position:relative;padding:5.33333px 0 5.33333px 10.66667px;cursor:pointer}.algolia-autocomplete .algolia-docsearch-suggestion--content:before{content:"";position:absolute;display:block;top:0;height:100%;width:1px;background:#ddd;left:-1px}.algolia-autocomplete .algolia-docsearch-suggestion--category-header{position:relative;border-bottom:1px solid #ddd;display:none;margin-top:8px;padding:4px 0;font-size:1em;color:#33363d}.algolia-autocomplete .algolia-docsearch-suggestion--wrapper{width:100%;float:left;padding:8px 0 0}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column{float:left;width:30%;text-align:right;position:relative;padding:5.33333px 10.66667px;color:#a4a7ae;font-size:.9em;word-wrap:break-word}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column:before{content:"";position:absolute;display:block;top:0;height:100%;width:1px;background:#ddd;right:0}.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-inline{display:none}.algolia-autocomplete .algolia-docsearch-suggestion--title{margin-bottom:4px;color:#02060c;font-size:.9em;font-weight:700}.algolia-autocomplete .algolia-docsearch-suggestion--text{display:block;line-height:1.2em;font-size:.85em;color:#63676d}.algolia-autocomplete .algolia-docsearch-suggestion--no-results{width:100%;padding:8px 0;text-align:center;font-size:1.2em}.algolia-autocomplete .algolia-docsearch-suggestion--no-results:before{display:none}.algolia-autocomplete .algolia-docsearch-suggestion code{padding:1px 5px;font-size:90%;border:none;color:#222;background-color:#ebebeb;border-radius:3px;font-family:Menlo,Monaco,Consolas,Courier New,monospace}.algolia-autocomplete .algolia-docsearch-suggestion code .algolia-docsearch-suggestion--highlight{background:none}.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__main .algolia-docsearch-suggestion--category-header,.algolia-autocomplete .algolia-docsearch-suggestion.algolia-docsearch-suggestion__secondary{display:block}@media (min-width:768px){.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{display:block}}@media (max-width:768px){.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{display:inline-block;width:auto;float:left;padding:0;color:#02060c;font-size:.9em;font-weight:700;text-align:left;opacity:.5}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:before{display:none}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:after{content:"|"}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content{display:inline-block;width:auto;text-align:left;float:left;padding:0}.algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content:before{display:none}}.algolia-autocomplete .suggestion-layout-simple.algolia-docsearch-suggestion{border-bottom:1px solid #eee;padding:8px;margin:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content{width:100%;padding:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--content:before{display:none}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header{margin:0;padding:0;display:block;width:100%;border:none}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl0,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1{opacity:.6;font-size:.85em}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--category-header-lvl1:before{background-image:url('data:image/svg+xml;utf8,');content:"";width:10px;height:10px;display:inline-block}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--wrapper{width:100%;float:left;margin:0;padding:0}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--duplicate-content,.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--subcategory-inline{display:none!important}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title{margin:0;color:#458ee1;font-size:.9em;font-weight:400}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--title:before{content:"#";font-weight:700;color:#458ee1;display:inline-block}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text{margin:4px 0 0;display:block;line-height:1.4em;padding:5.33333px 8px;background:#f8f8f8;font-size:.85em;opacity:.8}.algolia-autocomplete .suggestion-layout-simple .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight{color:#3f4145;font-weight:700;box-shadow:none}.algolia-autocomplete .algolia-docsearch-footer{width:134px;height:20px;z-index:2000;margin-top:10.66667px;float:right;font-size:0;line-height:0}.algolia-autocomplete .algolia-docsearch-footer--logo{background-image:url("data:image/svg+xml;charset=utf-8,%3Csvg width='168' height='24' xmlns='http://www.w3.org/2000/svg'%3E%3Cg fill='none' fill-rule='evenodd'%3E%3Cpath d='M78.988.938h16.594a2.968 2.968 0 012.966 2.966V20.5a2.967 2.967 0 01-2.966 2.964H78.988a2.967 2.967 0 01-2.966-2.964V3.897A2.961 2.961 0 0178.988.938zm41.937 17.866c-4.386.02-4.386-3.54-4.386-4.106l-.007-13.336 2.675-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-10.846-2.18c.821 0 1.43-.047 1.855-.129v-2.719a6.334 6.334 0 00-1.574-.199 5.7 5.7 0 00-.897.069 2.699 2.699 0 00-.814.24c-.24.116-.439.28-.582.491-.15.212-.219.335-.219.656 0 .628.219.991.616 1.23s.938.362 1.615.362zm-.233-9.7c.883 0 1.629.109 2.231.328.602.218 1.088.525 1.444.915.363.396.609.922.76 1.483.157.56.232 1.175.232 1.85v6.874a32.5 32.5 0 01-1.868.314c-.834.123-1.772.185-2.813.185-.69 0-1.327-.069-1.895-.198a4.001 4.001 0 01-1.471-.636 3.085 3.085 0 01-.951-1.134c-.226-.465-.343-1.12-.343-1.803 0-.656.13-1.073.384-1.525a3.24 3.24 0 011.047-1.106c.445-.287.95-.492 1.532-.615a8.8 8.8 0 011.82-.185 8.404 8.404 0 011.972.24v-.438c0-.307-.035-.6-.11-.874a1.88 1.88 0 00-.384-.73 1.784 1.784 0 00-.724-.493 3.164 3.164 0 00-1.143-.205c-.616 0-1.177.075-1.69.164a7.735 7.735 0 00-1.26.307l-.321-2.192c.335-.117.834-.233 1.478-.349a10.98 10.98 0 012.073-.178zm52.842 9.626c.822 0 1.43-.048 1.854-.13V13.7a6.347 6.347 0 00-1.574-.199c-.294 0-.595.021-.896.069a2.7 2.7 0 00-.814.24 1.46 1.46 0 00-.582.491c-.15.212-.218.335-.218.656 0 .628.218.991.615 1.23.404.245.938.362 1.615.362zm-.226-9.694c.883 0 1.629.108 2.231.327.602.219 1.088.526 1.444.915.355.39.609.923.759 1.483a6.8 6.8 0 01.233 1.852v6.873c-.41.088-1.034.19-1.868.314-.834.123-1.772.184-2.813.184-.69 0-1.327-.068-1.895-.198a4.001 4.001 0 01-1.471-.635 3.085 3.085 0 01-.951-1.134c-.226-.465-.343-1.12-.343-1.804 0-.656.13-1.073.384-1.524.26-.45.608-.82 1.047-1.107.445-.286.95-.491 1.532-.614a8.803 8.803 0 012.751-.13c.329.034.671.096 1.04.185v-.437a3.3 3.3 0 00-.109-.875 1.873 1.873 0 00-.384-.731 1.784 1.784 0 00-.724-.492 3.165 3.165 0 00-1.143-.205c-.616 0-1.177.075-1.69.164a7.75 7.75 0 00-1.26.307l-.321-2.193c.335-.116.834-.232 1.478-.348a11.633 11.633 0 012.073-.177zm-8.034-1.271a1.626 1.626 0 01-1.628-1.62c0-.895.725-1.62 1.628-1.62.904 0 1.63.725 1.63 1.62 0 .895-.733 1.62-1.63 1.62zm1.348 13.22h-2.689V7.27l2.69-.423v11.956zm-4.714 0c-4.386.02-4.386-3.54-4.386-4.107l-.008-13.336 2.676-.424v13.254c0 .322 0 2.358 1.718 2.364v2.248zm-8.698-5.903c0-1.156-.253-2.119-.746-2.788-.493-.677-1.183-1.01-2.067-1.01-.882 0-1.574.333-2.065 1.01-.493.676-.733 1.632-.733 2.788 0 1.168.246 1.953.74 2.63.492.683 1.183 1.018 2.066 1.018.882 0 1.574-.342 2.067-1.019.492-.683.738-1.46.738-2.63zm2.737-.007c0 .902-.13 1.584-.397 2.33a5.52 5.52 0 01-1.128 1.906 4.986 4.986 0 01-1.752 1.223c-.685.286-1.739.45-2.265.45-.528-.006-1.574-.157-2.252-.45a5.096 5.096 0 01-1.744-1.223c-.487-.527-.863-1.162-1.137-1.906a6.345 6.345 0 01-.41-2.33c0-.902.123-1.77.397-2.508a5.554 5.554 0 011.15-1.892 5.133 5.133 0 011.75-1.216c.679-.287 1.425-.423 2.232-.423.808 0 1.553.142 2.237.423a4.88 4.88 0 011.753 1.216 5.644 5.644 0 011.135 1.892c.287.738.431 1.606.431 2.508zm-20.138 0c0 1.12.246 2.363.738 2.882.493.52 1.13.78 1.91.78.424 0 .828-.062 1.204-.178.377-.116.677-.253.917-.417V9.33a10.476 10.476 0 00-1.766-.226c-.971-.028-1.71.37-2.23 1.004-.513.636-.773 1.75-.773 2.788zm7.438 5.274c0 1.824-.466 3.156-1.404 4.004-.936.846-2.367 1.27-4.296 1.27-.705 0-2.17-.137-3.34-.396l.431-2.118c.98.205 2.272.26 2.95.26 1.074 0 1.84-.219 2.299-.656.459-.437.684-1.086.684-1.948v-.437a8.07 8.07 0 01-1.047.397c-.43.13-.93.198-1.492.198-.739 0-1.41-.116-2.018-.349a4.206 4.206 0 01-1.567-1.025c-.431-.45-.774-1.017-1.013-1.694-.24-.677-.363-1.885-.363-2.773 0-.834.13-1.88.384-2.577.26-.696.629-1.298 1.129-1.796.493-.498 1.095-.881 1.8-1.162a6.605 6.605 0 012.428-.457c.87 0 1.67.109 2.45.24.78.129 1.444.265 1.985.415V18.17z' fill='%235468FF'/%3E%3Cpath d='M6.972 6.677v1.627c-.712-.446-1.52-.67-2.425-.67-.585 0-1.045.13-1.38.391a1.24 1.24 0 00-.502 1.03c0 .425.164.765.494 1.02.33.256.835.532 1.516.83.447.192.795.356 1.045.495.25.138.537.332.862.582.324.25.563.548.718.894.154.345.23.741.23 1.188 0 .947-.334 1.691-1.004 2.234-.67.542-1.537.814-2.601.814-1.18 0-2.16-.229-2.936-.686v-1.708c.84.628 1.814.942 2.92.942.585 0 1.048-.136 1.388-.407.34-.271.51-.646.51-1.125 0-.287-.1-.55-.302-.79-.203-.24-.42-.42-.655-.542-.234-.123-.585-.29-1.053-.503a61.27 61.27 0 01-.582-.271 13.67 13.67 0 01-.55-.287 4.275 4.275 0 01-.567-.351 6.92 6.92 0 01-.455-.4c-.18-.17-.31-.34-.39-.51-.08-.17-.155-.37-.224-.598a2.553 2.553 0 01-.104-.742c0-.915.333-1.638.998-2.17.664-.532 1.523-.798 2.576-.798.968 0 1.793.17 2.473.51zm7.468 5.696v-.287c-.022-.607-.187-1.088-.495-1.444-.309-.357-.75-.535-1.324-.535-.532 0-.99.194-1.373.583-.382.388-.622.949-.717 1.683h3.909zm1.005 2.792v1.404c-.596.34-1.383.51-2.362.51-1.255 0-2.255-.377-3-1.132-.744-.755-1.116-1.744-1.116-2.968 0-1.297.34-2.316 1.021-3.055.68-.74 1.548-1.11 2.6-1.11 1.033 0 1.852.323 2.458.966.606.644.91 1.572.91 2.784 0 .33-.033.676-.096 1.038h-5.314c.107.702.405 1.239.894 1.611.49.372 1.106.558 1.85.558.862 0 1.58-.202 2.155-.606zm6.605-1.77h-1.212c-.596 0-1.045.116-1.349.35-.303.234-.454.532-.454.894 0 .372.117.664.35.877.235.213.575.32 1.022.32.51 0 .912-.142 1.204-.424.293-.281.44-.651.44-1.108v-.91zm-4.068-2.554V9.325c.627-.361 1.457-.542 2.489-.542 2.116 0 3.175 1.026 3.175 3.08V17h-1.548v-.957c-.415.68-1.143 1.02-2.186 1.02-.766 0-1.38-.22-1.843-.661-.462-.442-.694-1.003-.694-1.684 0-.776.293-1.38.878-1.81.585-.431 1.404-.647 2.457-.647h1.34V11.8c0-.554-.133-.971-.399-1.253-.266-.282-.707-.423-1.324-.423a4.07 4.07 0 00-2.345.718zm9.333-1.93v1.42c.394-1 1.101-1.5 2.123-1.5.148 0 .313.016.494.048v1.531a1.885 1.885 0 00-.75-.143c-.542 0-.989.24-1.34.718-.351.479-.527 1.048-.527 1.707V17h-1.563V8.91h1.563zm5.01 4.084c.022.82.272 1.492.75 2.019.479.526 1.15.79 2.01.79.639 0 1.235-.176 1.788-.527v1.404c-.521.319-1.186.479-1.995.479-1.265 0-2.276-.4-3.031-1.197-.755-.798-1.133-1.792-1.133-2.984 0-1.16.38-2.151 1.14-2.975.761-.825 1.79-1.237 3.088-1.237.702 0 1.346.149 1.93.447v1.436a3.242 3.242 0 00-1.77-.495c-.84 0-1.513.266-2.019.798-.505.532-.758 1.213-.758 2.042zM40.24 5.72v4.579c.458-1 1.293-1.5 2.505-1.5.787 0 1.42.245 1.899.734.479.49.718 1.17.718 2.042V17h-1.564v-5.106c0-.553-.14-.98-.422-1.284-.282-.303-.652-.455-1.11-.455-.531 0-1.002.202-1.411.606-.41.405-.615 1.022-.615 1.851V17h-1.563V5.72h1.563zm14.966 10.02c.596 0 1.096-.253 1.5-.758.404-.506.606-1.157.606-1.955 0-.915-.202-1.62-.606-2.114-.404-.495-.92-.742-1.548-.742-.553 0-1.05.224-1.491.67-.442.447-.662 1.133-.662 2.058 0 .958.212 1.67.638 2.138.425.469.946.703 1.563.703zM53.004 5.72v4.42c.574-.894 1.388-1.341 2.44-1.341 1.022 0 1.857.383 2.506 1.149.649.766.973 1.781.973 3.047 0 1.138-.309 2.109-.925 2.912-.617.803-1.463 1.205-2.537 1.205-1.075 0-1.894-.447-2.457-1.34V17h-1.58V5.72h1.58zm9.908 11.104l-3.223-7.913h1.739l1.005 2.632 1.26 3.415c.096-.32.48-1.458 1.15-3.415l.909-2.632h1.66l-2.92 7.866c-.777 2.074-1.963 3.11-3.559 3.11a2.92 2.92 0 01-.734-.079v-1.34c.17.042.351.064.543.064 1.032 0 1.755-.57 2.17-1.708z' fill='%235D6494'/%3E%3Cpath d='M89.632 5.967v-.772a.978.978 0 00-.978-.977h-2.28a.978.978 0 00-.978.977v.793c0 .088.082.15.171.13a7.127 7.127 0 011.984-.28c.65 0 1.295.088 1.917.259.082.02.164-.04.164-.13m-6.248 1.01l-.39-.389a.977.977 0 00-1.382 0l-.465.465a.973.973 0 000 1.38l.383.383c.062.061.15.047.205-.014.226-.307.472-.601.746-.874.281-.28.568-.526.883-.751.068-.042.075-.137.02-.2m4.16 2.453v3.341c0 .096.104.165.192.117l2.97-1.537c.068-.034.089-.117.055-.184a3.695 3.695 0 00-3.08-1.866c-.068 0-.136.054-.136.13m0 8.048a4.489 4.489 0 01-4.49-4.482 4.488 4.488 0 014.49-4.482 4.488 4.488 0 014.489 4.482 4.484 4.484 0 01-4.49 4.482m0-10.85a6.363 6.363 0 100 12.729 6.37 6.37 0 006.372-6.368 6.358 6.358 0 00-6.371-6.36' fill='%23FFF'/%3E%3C/g%3E%3C/svg%3E");background-repeat:no-repeat;background-position:50%;background-size:100%;overflow:hidden;text-indent:-9000px;padding:0!important;width:100%;height:100%;display:block}.slider{max-width:1200px;margin:0 auto;padding-left:1rem;padding-right:1rem}.slider .VueCarousel-pagination{margin-top:-40px}@media(min-width:768px){.slider{max-width:640px;padding-left:0;padding-right:0}}@media(min-width:1000px){.slider{max-width:910px}}@media(min-width:1300px){.slider{max-width:1200px}}.VueCarousel-slide{overflow-x:hidden}.VueCarousel-navigation-prev{width:15px;height:15px;border-top:2px solid #2c3e50!important;border-right:2px solid #2c3e50!important;transform:rotate(-135deg)!important;padding:0!important;left:-30px!important}@media(min-width:1000px){.VueCarousel-navigation-prev{left:-20px!important}}.VueCarousel-navigation-next{width:15px;height:15px;border-top:2px solid #2c3e50!important;border-right:2px solid #2c3e50!important;transform:rotate(45deg)!important;padding:0!important;right:-30px!important}@media(min-width:1000px){.VueCarousel-navigation-next{right:-20px!important}}@media(max-width:767px){.VueCarousel-navigation-button{display:none}}.VueCarousel-navigation-button:focus{outline:none!important}.slide{display:flex;align-items:center;flex-direction:column}@media(min-width:1000px){.slide{flex-direction:row}}.slide img{width:100%;--border-opacity:1;border:5px solid #edf2f7;border-color:rgba(237,242,247,var(--border-opacity));box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06);border-radius:.5rem}@media(min-width:1000px){.slide img{margin-right:1rem;width:50%;height:50%}}.slide>div{flex:1 1 0%;width:100%}.slider[data-v-59131a2e]{max-width:1200px;margin:0 auto;padding-left:1rem;padding-right:1rem}.slider .VueCarousel-pagination[data-v-59131a2e]{margin-top:-40px}@media(min-width:768px){.slider[data-v-59131a2e]{max-width:640px;padding-left:0;padding-right:0}}@media(min-width:1000px){.slider[data-v-59131a2e]{max-width:910px}}@media(min-width:1300px){.slider[data-v-59131a2e]{max-width:1200px}}.VueCarousel-slide[data-v-59131a2e]{overflow-x:hidden;display:flex}.VueCarousel-navigation-prev[data-v-59131a2e]{transform:rotate(-135deg)!important;left:-30px!important}.VueCarousel-navigation-next[data-v-59131a2e],.VueCarousel-navigation-prev[data-v-59131a2e]{width:15px;height:15px;border-top:2px solid #2c3e50!important;border-right:2px solid #2c3e50!important;padding:0!important}.VueCarousel-navigation-next[data-v-59131a2e]{transform:rotate(45deg)!important;right:-30px!important}@media(max-width:767px){.VueCarousel-navigation-button[data-v-59131a2e]{display:none}}.VueCarousel-navigation-button[data-v-59131a2e]:focus{outline:none!important}.slide[data-v-59131a2e]{width:100%;display:flex;align-items:center;justify-content:space-around;flex-direction:row}@media(min-width:1000px){.slide img[data-v-59131a2e]{border:none;padding:.25rem;margin-top:1rem;margin-bottom:1rem;box-shadow:none}}.slide img[data-v-59131a2e]{filter:grayscale(.9);flex:none;border-radius:.75rem;height:100%;max-height:100px;-webkit-transition:-webkit-filter .5s linear;width:auto;border:none;padding:.25rem;margin:1rem auto;box-shadow:none}@media(max-width:767px){.slide img[data-v-59131a2e]{max-height:180px!important}.slide img.mynd-img[data-v-59131a2e]{max-height:130px!important}}.slide img[data-v-59131a2e]:hover{filter:grayscale(0)}.slide>div[data-v-59131a2e]{flex:1 1 0%;width:100%}.sectionLayout footer section[data-v-5616cc4e]{margin:auto;max-width:860px}footer[data-v-5616cc4e]{border-top:5px dashed #fff;--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}footer .copyright[data-v-5616cc4e]{color:#fff;--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity));padding-top:.5rem;padding-bottom:.5rem;text-align:center;font-size:.75rem;--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity));border-top:5px dashed;border-top-color:rgba(237,242,247,var(--border-opacity))}footer ul[data-v-5616cc4e]{list-style-type:none;list-style-position:outside;padding-left:0;margin-left:0}footer .important[data-v-5616cc4e]{position:relative}footer .important[data-v-5616cc4e]:before{content:"";position:absolute;left:-18px;top:50%;transform:translateY(-50%);width:10px;height:10px;border-radius:100%;background-color:#f56565}footer h5[data-v-5616cc4e]{margin-bottom:1rem;font-size:.75rem;text-transform:uppercase}footer section[data-v-5616cc4e]{max-width:960px;margin:0 auto;padding:1rem 2rem;display:flex;justify-content:space-around}footer section .col[data-v-5616cc4e]{flex:1 1 0%;padding-left:.5rem;padding-right:.5rem}@media(max-width:600px){footer section[data-v-5616cc4e]{display:block;padding-left:1rem;padding-right:1rem}}.algolia-search-wrapper>span{vertical-align:middle}.algolia-search-wrapper .algolia-autocomplete{line-height:normal}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu{background-color:#fff;border:1px solid #999;border-radius:4px;font-size:16px;margin:6px 0 0;padding:4px;text-align:left}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu:before{border-color:#999}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu [class*=ds-dataset-]{border:none;padding:0}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu .ds-suggestions{margin-top:0}.algolia-search-wrapper .algolia-autocomplete .ds-dropdown-menu .ds-suggestion{border-bottom:1px solid #eaecef}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion--highlight{color:#2c815b}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion{border-color:#eaecef;padding:0}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--category-header{padding:5px 10px;margin-top:0;background:#553c9a;color:#fff;font-weight:600}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--category-header .algolia-docsearch-suggestion--highlight{background:hsla(0,0%,100%,.6)}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--wrapper{padding:0}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--title{font-weight:600;margin-bottom:0;color:#2c3e50}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{vertical-align:top;padding:5px 7px 5px 5px;border-color:#eaecef;background:#f1f3f5}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column:after{display:none}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column-text{color:#555}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-footer{border-color:#eaecef}.algolia-search-wrapper .algolia-autocomplete .ds-cursor .algolia-docsearch-suggestion--content{background-color:#e7edf3!important;color:#2c3e50}@media (min-width:719px){.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--subcategory-column{float:none;width:150px;min-width:150px;display:table-cell}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .algolia-docsearch-suggestion--content{float:none;display:table-cell;width:100%;vertical-align:top}.algolia-search-wrapper .algolia-autocomplete .algolia-docsearch-suggestion .ds-dropdown-menu{min-width:515px!important}}@media (max-width:719px){.algolia-search-wrapper .ds-dropdown-menu{min-width:calc(100vw - 4rem)!important;max-width:calc(100vw - 4rem)!important}.algolia-search-wrapper .algolia-docsearch-suggestion--wrapper{padding:5px 7px 5px 5px!important}.algolia-search-wrapper .algolia-docsearch-suggestion--subcategory-column{padding:0!important;background:#fff!important}.algolia-search-wrapper .algolia-docsearch-suggestion--subcategory-column-text:after{content:" > ";font-size:10px;line-height:14.4px;display:inline-block;width:5px;margin:-3px 3px 0;vertical-align:middle}}.search-box{display:inline-block;position:relative;margin-right:1rem}.search-box input{cursor:text;width:10rem;height:2rem;color:#4e6e8e;display:inline-block;border:1px solid #cfd4db;border-radius:2rem;font-size:.9rem;line-height:2rem;padding:0 .5rem 0 2rem;outline:none;transition:all .2s ease;background:#fff url(/assets/img/search.83621669.svg) .6rem .5rem no-repeat;background-size:1rem}.search-box input:focus{cursor:auto;border-color:#553c9a}.search-box .suggestions{background:#fff;width:20rem;position:absolute;top:2rem;border:1px solid #cfd4db;border-radius:6px;padding:.4rem;list-style-type:none}.search-box .suggestions.align-right{right:0}.search-box .suggestion{line-height:1.4;padding:.4rem .6rem;border-radius:4px;cursor:pointer}.search-box .suggestion a{white-space:normal;color:#5d82a6}.search-box .suggestion a .page-title{font-weight:600}.search-box .suggestion a .header{font-size:.9em;margin-left:.25em}.search-box .suggestion.focused{background-color:#f3f4f5}.search-box .suggestion.focused a{color:#553c9a}@media (max-width:959px){.search-box input{cursor:pointer;width:0;border-color:transparent;position:relative}.search-box input:focus{cursor:text;left:0;width:10rem}}@media (-ms-high-contrast:none){.search-box input{height:2rem}}@media (max-width:959px) and (min-width:719px){.search-box .suggestions{left:0}}@media (max-width:719px){.search-box{margin-right:0}.search-box input{left:1rem}.search-box .suggestions{right:0}}@media (max-width:419px){.search-box .suggestions{width:calc(100vw - 4rem)}.search-box input:focus{width:8rem}}.sidebar-button{cursor:pointer;display:none;width:1.25rem;height:1.25rem;position:absolute;padding:.6rem;top:.6rem;left:.5rem}.sidebar-button .icon{display:block;width:1.25rem;height:1.25rem}@media (max-width:1150px){.sidebar-button{display:block}}a[data-v-34dbfd23]{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity))}.dropdown-enter,.dropdown-leave-to{height:0!important}.banner[data-v-436508ca]{padding:1em;background-color:#fefcbf;text-align:center}.banner a[data-v-436508ca]{font-weight:700;color:#805ad5}.banner a[data-v-436508ca]:hover{text-decoration:underline}.mountains[data-v-e3b729f8]{background:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='1900' height='650' viewBox='0 0 1600 900'%3E%3Cpath fill='%2376509a' d='M957 450L539 900h857z'/%3E%3Cpath fill='%2332184b' d='M957 450l-84.1 450H1396z'/%3E%3Cpath fill='%237b53a0' d='M-60 900l458-238 418 238z'/%3E%3Cpath fill='%233c1d5a' d='M337 900l61-238 418 238z'/%3E%3Cpath fill='%237e59a1' d='M1203 546l349 354H876z'/%3E%3Cpath fill='%2347236a' d='M1203 546l349 354h-390z'/%3E%3Cpath fill='%23815ea6' d='M641 695l245 205H367z'/%3E%3Cpath fill='%2352277a' d='M587 900l54-205 245 205z'/%3E%3Cpath fill='%238661ab' d='M1710 900l-309-268-305 268z'/%3E%3Cpath fill='%235b2d88' d='M1710 900l-309-268-36 268z'/%3E%3Cpath fill='%238c61b4' d='M1210 900L971 687 725 900z'/%3E%3Cpath fill='%2367329b' d='M943 900h267L971 687z'/%3E%3C/svg%3E");background-position:0 100%;background-repeat:no-repeat;margin-left:-2rem;margin-right:-2rem}.content[data-v-e3b729f8]{padding-bottom:2rem}.playwright-home[data-v-e3b729f8]{margin-top:10px}.badge[data-v-e3b729f8]{--bg-opacity:1;background-color:#f6e05e;background-color:rgba(246,224,94,var(--bg-opacity));--text-opacity:1;color:#553c9a;color:rgba(85,60,154,var(--text-opacity));padding:.25rem .5rem;border-radius:.5rem;font-size:.875rem}.testomatio[data-v-e3b729f8]{padding-top:4rem;padding-bottom:4rem;line-height:2rem;text-align:center;--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity));font-size:1.125rem}.testimonials[data-v-e3b729f8],.testomatio[data-v-e3b729f8]{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity));border-top:5px dashed;border-top-color:rgba(237,242,247,var(--border-opacity))}.testimonials[data-v-e3b729f8]{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity));margin-top:1rem;padding-top:2rem;padding-bottom:2rem}.testimonials .inner[data-v-e3b729f8]{max-width:960px;margin:0 auto;padding-left:1rem;padding-right:1rem}.testimonials .inner .commercial[data-v-e3b729f8]{border:5px dashed #fff;line-height:2;border-radius:.25rem;text-align:center;margin-top:2rem;--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity));--text-opacity:1;color:#4a5568;color:rgba(74,85,104,var(--text-opacity));padding:2rem}.testimonials .inner .row[data-v-e3b729f8]{display:flex}.testimonials .inner .row .quote[data-v-e3b729f8]{flex:1 1 0%}.testimonials .inner .row .quote .signature[data-v-e3b729f8]{display:flex;align-items:center;align-content:center}.testimonials .inner .row .quote p[data-v-e3b729f8]{position:relative;font-size:.875rem;--text-opacity:1;color:#718096;color:rgba(113,128,150,var(--text-opacity));padding:1rem 1rem 1rem 2.5rem}.testimonials .inner .row .quote p[data-v-e3b729f8]:before{content:"“";font-size:72px;--text-opacity:1;color:#63b3ed;color:rgba(99,179,237,var(--text-opacity));position:absolute;top:0;left:0}.testimonials .inner .row .quote img[data-v-e3b729f8]{border-radius:30px;width:60px;height:60px;margin-right:1rem;flex:0 1 auto}.testimonials .inner .row .quote .position[data-v-e3b729f8]{font-size:.875rem;flex:1 1 0%;padding-right:1rem}.frameworks[data-v-e3b729f8]{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity));--border-opacity:1;border-color:#f7fafc;border-left-color:rgba(247,250,252,var(--border-opacity));border-bottom:5px dashed;border-bottom-color:rgba(247,250,252,var(--border-opacity));border-right-color:rgba(247,250,252,var(--border-opacity));border-top-color:rgba(247,250,252,var(--border-opacity));text-align:center}.frameworks img[data-v-e3b729f8]{filter:grayscale(1);width:50px;height:50px;vertical-align:middle}.frameworks img[data-v-e3b729f8]:hover{filter:grayscale(0)}.demos[data-v-e3b729f8]{--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity));margin-top:1rem;margin-bottom:1rem;padding-top:2rem;padding-bottom:2rem;--border-opacity:1;border-color:#f7fafc;border-bottom:5px dashed;border-color:rgba(247,250,252,var(--border-opacity));border-top:5px dashed;border-top-color:rgba(247,250,252,var(--border-opacity))}.features[data-v-e3b729f8]{display:flex;margin-top:.5rem;margin-bottom:.5rem}.features img[data-v-e3b729f8]{width:120px;margin-right:1rem;opacity:.8;transition:opacity 1s}.features img[data-v-e3b729f8]:hover{opacity:1}.feature[data-v-e3b729f8]{width:33.333333%;display:flex;margin-bottom:2.5rem;--border-opacity:1;border-color:#fff;border-color:rgba(255,255,255,var(--border-opacity));padding-left:.25rem;align-items:flex-start}.feature .inner[data-v-e3b729f8]{line-height:1.75;flex:1 1 0%;padding-right:1rem;text-align:left}.feature a[data-v-e3b729f8]{border-radius:.25rem;--bg-opacity:1;background-color:#fff;background-color:rgba(255,255,255,var(--bg-opacity));padding-left:.5rem;padding-right:.5rem;display:inline-block}.feature:last-child .inner[data-v-e3b729f8]{padding-right:0}.features h5[data-v-e3b729f8]{margin-top:0;margin-bottom:15px;font-size:100%;line-height:1.5}@media(max-width:600px){.frameworks[data-v-e3b729f8]{display:none}.home .content[data-v-e3b729f8]{padding-top:2rem;max-width:100%;font-size:.875rem;padding-left:1rem;padding-right:1rem}body .features .feature[data-v-e3b729f8]{width:100%;padding-left:0;padding-right:0;font-size:.875rem}body .features .feature img[data-v-e3b729f8]{width:48px;height:48px;margin-right:5px}body .testomatio[data-v-e3b729f8]{display:none}body .testimonials .companies[data-v-e3b729f8]{zoom:.5;overflow:hidden}body .testimonials .row[data-v-e3b729f8]{display:block!important}}@media(max-width:1200px){.feature[data-v-e3b729f8]{padding:0}}@media(min-width:719px)and (max-width:1023px){.features img[data-v-e3b729f8]{width:50px}}.home{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity));max-width:100%;display:block}.home h1{--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity));margin-bottom:2rem}.home h1 .name{--text-opacity:1;color:#edf2f7;color:rgba(237,242,247,var(--text-opacity))}.home .ai{font-size:.875rem;text-transform:capitalize;letter-spacing:.1em;font-weight:700}.home .ai a{color:#fff}.home .hero{padding:3.6rem 2rem 0;--text-opacity:1;color:#cbd5e0;color:rgba(203,213,224,var(--text-opacity));border-top:5px dashed #8065d5;margin-top:3.6rem;border-bottom:5px dashed #fff;background-image:url(/img/back.png);background-color:#805ad5;text-align:center}.home .hero pre>code{--bg-opacity:1;background-color:#1a202c;background-color:rgba(26,32,44,var(--bg-opacity));--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity));padding:.5rem 2rem;border-radius:.25rem}.home .hero .video{margin-top:-30px}.home .hero .video a{cursor:pointer;border-bottom:1px dashed #fff;z-index:1000;--text-opacity:1;color:#fff;color:rgba(255,255,255,var(--text-opacity));font-size:.875rem}.home .hero .video .videoModal{position:fixed;top:0;left:0;right:0;bottom:0;padding:20px;display:flex;align-items:center;justify-content:center;background:hsla(0,0%,100%,.5);z-index:200}.home .hero .video .videoModal video{z-index:10000;max-width:800px}.home .hero img{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04);border-radius:.25rem;max-width:600px;width:100%;display:block;margin:3rem auto 1.5rem}.home .hero h1{font-size:3rem}.home .hero .action,.home .hero .description{margin:1.8rem auto 0}.home .hero .description{max-width:35rem;font-size:1.6rem;line-height:1.3;color:#6a8bad}.home .hero .action-button{box-shadow:0 20px 25px -5px rgba(0,0,0,.1),0 10px 10px -5px rgba(0,0,0,.04);display:inline-block;font-size:1.8rem;color:#fff;background-color:#553c9a;padding:1rem 3rem;border-radius:4px;border:1px solid hsla(0,0%,100%,.5);border-bottom:none;transition:background-color .1s ease;box-sizing:border-box;margin-bottom:-60px}.home .hero .action-button:hover{background-color:#6144af}.home .content{max-width:1200px;margin:0 auto;padding-top:3rem;padding-left:1rem;padding-right:1rem}.home .footer{padding:2.5rem;border-top:1px solid #eaecef;text-align:center;color:#4e6e8e}@media (max-width:719px){.home .features{flex-direction:column}.home .feature{max-width:100%;width:100%;padding:0 2.5rem;box-sizing:border-box}}@media (max-width:419px){.home{padding:0}.home .hero .video{margin-top:20px}.home .hero img{display:none;max-height:210px;margin:2rem auto 1.2rem}.home .hero h1{font-size:2rem}.home .hero .action,.home .hero .description,.home .hero h1{margin:1.2rem auto}.home .hero .description{font-size:1.2rem}.home .hero .action-button{font-size:1rem;padding:.6rem 1.2rem}.home .feature h2{font-size:1.25rem}}.dropdown-wrapper{cursor:pointer}.dropdown-wrapper .dropdown-title{display:block;font-size:1rem;font-weight:600;font-family:inherit;cursor:inherit;padding:inherit;line-height:1.4rem;background:transparent;border:none;color:#fff}.dropdown-wrapper .dropdown-title:hover{border-color:transparent}.dropdown-wrapper .dropdown-title:focus{outline:none}.dropdown-wrapper .dropdown-title .arrow{vertical-align:middle;margin-top:-1px;margin-left:.4rem}.dropdown-wrapper .nav-dropdown .dropdown-item{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity));line-height:1.7rem}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-item-title,.dropdown-wrapper .nav-dropdown .dropdown-item h4{margin:.45rem 0 0;border-top:1px solid #eee;padding:.45rem 1.5rem 0 1.25rem}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem-wrapper{padding:0;list-style:none}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem-wrapper .dropdown-subitem{font-size:.9em}.dropdown-wrapper .nav-dropdown .dropdown-item a{display:block;line-height:1.7rem;position:relative;border-bottom:none;font-weight:400;margin-bottom:0;--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity));padding:0 1.5rem 0 1.25rem}.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active,.dropdown-wrapper .nav-dropdown .dropdown-item a:hover{--text-opacity:1;color:#1a202c;color:rgba(26,32,44,var(--text-opacity))}.dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active:after{content:"";width:0;height:0;border-left:5px solid #6b46c1;border-top:3px solid transparent;border-bottom:3px solid transparent;position:absolute;top:calc(50% - 2px);left:9px}.dropdown-wrapper .nav-dropdown .dropdown-item:first-child .dropdown-item-title,.dropdown-wrapper .nav-dropdown .dropdown-item:first-child h4{margin-top:0;padding-top:0;border-top:0}@media (max-width:719px){.dropdown-wrapper.open .dropdown-title{margin-bottom:.5rem}.dropdown-wrapper .dropdown-title{--text-opacity:1;color:#2d3748;color:rgba(45,55,72,var(--text-opacity));font-weight:600;font-size:inherit}.dropdown-wrapper .dropdown-title:hover{color:#553c9a}.dropdown-wrapper .nav-dropdown{transition:height .1s ease-out;overflow:hidden}.dropdown-wrapper .nav-dropdown .dropdown-item h4{border-top:0;margin-top:0;padding-top:0}.dropdown-wrapper .nav-dropdown .dropdown-item>a,.dropdown-wrapper .nav-dropdown .dropdown-item h4{font-size:15px;line-height:2rem}.dropdown-wrapper .nav-dropdown .dropdown-item .dropdown-subitem{font-size:14px;padding-left:1rem}}@media (min-width:719px){.dropdown-wrapper{height:1.8rem}.dropdown-wrapper.open .nav-dropdown,.dropdown-wrapper:hover .nav-dropdown{display:block!important}.dropdown-wrapper.open:blur{display:none}.dropdown-wrapper .dropdown-title .arrow{border-left:4px solid transparent;border-right:4px solid transparent;border-top:6px solid #ccc;border-bottom:0}.dropdown-wrapper .nav-dropdown{display:none;height:auto!important;box-sizing:border-box;max-height:calc(100vh - 2.7rem);overflow-y:auto;position:absolute;top:100%;right:0;background-color:#fff;padding:.6rem 0;box-shadow:0 0 0 1px #ddd;border-bottom-color:#ccc;text-align:left;border-radius:.25rem;white-space:nowrap;margin:0}}.nav-links{display:inline-block}.nav-links a{line-height:1.4rem;color:inherit}.nav-links .nav-item{position:relative;display:inline-block;margin-left:1.5rem;line-height:2rem}.nav-links .nav-item:first-child{margin-left:0}.nav-links .repo-link{margin-left:1.5rem}@media (max-width:719px){.nav-links .nav-item,.nav-links .repo-link{margin-left:0}.nav-item>a:not(.external).router-link-active,.nav-item>a:not(.external):hover{margin-bottom:-2px}}.navbar{box-shadow:0 4px 6px -1px rgba(0,0,0,.1),0 2px 4px -1px rgba(0,0,0,.06)}.navbar,.navbar .links{--bg-opacity:1;background-color:#805ad5;background-color:rgba(128,90,213,var(--bg-opacity))}.navbar .site-name,.navbar a{font-weight:600;color:#fff}.navbar{padding:.7rem 1.5rem;line-height:2.2rem}.navbar a,.navbar img,.navbar span{display:inline-block}.navbar .logo{height:2.2rem;min-width:2.2rem;vertical-align:top}.navbar .site-name{font-size:1.3rem;font-weight:600;color:#fff;position:relative}.navbar .links{padding-left:1.5rem;box-sizing:border-box;white-space:nowrap;font-size:1rem;font-weight:600;position:absolute;right:1.5rem;top:.7rem;display:flex}.navbar .links .search-box{flex:0 0 auto;vertical-align:top}@media (max-width:959px){.navbar .links .search-box input{width:10rem}}@media (max-width:768px){.navbar .links .search-box input{width:0}.navbar .links .search-box input:focus{width:10rem}}@media (max-width:419px){.navbar .links .search-box input:focus{width:8rem}}@media (max-width:719px){.navbar .site-name{width:calc(100vw - 9.4rem);overflow:hidden;white-space:nowrap;text-overflow:ellipsis}}@media (max-width:1150px){.navbar{padding-left:3rem;padding-right:1rem}.navbar .can-hide{display:none}.navbar .links{padding-left:1.5rem;right:1rem}.navbar .search-box{margin-right:0}}@media (max-width:1150px){.navbar .site-name{display:inline-block}}@media (max-width:767px){.navbar .site-name{display:none}}.page-edit{max-width:760px;margin:1rem auto;padding:2rem 1rem}@media (max-width:959px){.page-edit{padding:2rem}}@media (max-width:419px){.page-edit{padding:1.5rem 1rem}.page-edit li,.page-edit p{word-break:break-word}}.page-edit{padding-top:1rem;padding-bottom:1rem;overflow:auto}.page-edit .edit-link{display:inline-block}.page-edit .edit-link a{color:#4e6e8e;margin-right:.25rem}.page-edit .last-updated{float:right;font-size:.9em}.page-edit .last-updated .prefix{font-weight:500;color:#4e6e8e}.page-edit .last-updated .time{font-weight:400;color:#aaa}@media (max-width:719px){.page-edit .edit-link{margin-bottom:.5rem}.page-edit .last-updated{font-size:.8em;float:none;text-align:left}}.page-nav{max-width:760px;margin:1rem auto;padding:2rem 1rem}@media (max-width:959px){.page-nav{padding:2rem}}@media (max-width:419px){.page-nav{padding:1.5rem 1rem}.page-nav li,.page-nav p{word-break:break-word}}.page-nav{padding-top:1rem;padding-bottom:0}.page-nav .inner{min-height:2rem;margin-top:0;border-top:1px solid #eaecef;padding-top:1rem;overflow:auto}.page-nav .next{float:right}.sidebar[data-v-0dc4070a]{position:fixed;top:3.6rem;left:auto;right:0;bottom:0;opacity:.7;transition:opacity .2s;font-size:.875rem;--bg-opacity:1;background-color:ivory;background-color:rgba(255,255,240,var(--bg-opacity));border-radius:.25rem}.sidebar[data-v-0dc4070a]:hover{opacity:1}.sidebar p[data-v-0dc4070a]{margin-top:1rem;margin-bottom:1rem}.sidebar a[data-v-0dc4070a]{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.sidebar .border[data-v-0dc4070a]{--border-opacity:1;border:2px solid #cbd5e0;border-color:rgba(203,213,224,var(--border-opacity));padding:.5rem 1rem}.sidebar a.dashed[data-v-0dc4070a]{--border-opacity:1;border-color:#edf2f7;border-color:rgba(237,242,247,var(--border-opacity));--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity));border-bottom:1px dashed}.sidebar-wrapper[data-v-0dc4070a]{padding:1rem 2rem}@media(max-width:1400px){.sidebar[data-v-0dc4070a]{display:none}}code[class*=language-],pre[class*=language-]{text-align:left;white-space:pre;word-spacing:normal;word-break:normal;word-wrap:normal;color:#eee;background:#2f2f2f;font-family:Roboto Mono,monospace;font-size:1em;line-height:1.5em;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-hyphens:none;-moz-hyphens:none;-ms-hyphens:none;hyphens:none}code[class*=language-]::-moz-selection,code[class*=language-] ::-moz-selection,pre[class*=language-]::-moz-selection,pre[class*=language-] ::-moz-selection{background:#363636}code[class*=language-]::selection,code[class*=language-] ::selection,pre[class*=language-]::selection,pre[class*=language-] ::selection{background:#363636}:not(pre)>code[class*=language-]{white-space:normal;border-radius:.2em;padding:.1em}pre[class*=language-]{overflow:auto;position:relative;margin:.5em 0;padding:1.25em 1em}.language-css>code,.language-sass>code,.language-scss>code{color:#fd9170}[class*=language-] .namespace{opacity:.7}.token.atrule{color:#c792ea}.token.attr-name{color:#ffcb6b}.token.attr-value,.token.attribute{color:#a5e844}.token.boolean{color:#c792ea}.token.builtin{color:#ffcb6b}.token.cdata,.token.char{color:#80cbc4}.token.class{color:#ffcb6b}.token.class-name{color:#f2ff00}.token.comment{color:#999}.token.constant{color:#e6c07b;font-weight:700}.token.deleted{color:#f66}.token.doctype{color:#999}.token.entity{color:#f66}.token.function{color:#e0ebf7}.token.hexcode{color:#f2ff00}.token.id,.token.important{color:#c792ea;font-weight:700}.token.inserted{color:#80cbc4}.token.keyword{color:#c792ea}.token.number{color:#fd9170}.token.operator{color:#89ddff}.token.prolog{color:#616161}.token.property{color:#80cbc4}.token.pseudo-class,.token.pseudo-element{color:#a5e844}.token.punctuation{color:#89ddff}.token.regex{color:#f2ff00}.token.selector{color:#f66}.token.string{color:#c9fba5}.token.symbol{color:#c792ea}.token.tag{color:#f66}.token.unit{color:#fd9170}.token.url,.token.variable{color:#f66}.article-title{--text-opacity:1;color:#000;color:rgba(0,0,0,var(--text-opacity));text-transform:uppercase}.page{display:block}.page footer section{max-width:760px}.sidebar .sidebar-sub-headers{padding-left:1rem;font-size:.95em;scrollbar-color:#cbd5e0 #718096;scrollbar-width:5px}a.sidebar-link{font-size:1em;font-weight:400;display:inline-block;color:#2c3e50;border-left:.25rem solid transparent;padding:.35rem 1rem .35rem 1.25rem;line-height:1.4;width:100%;box-sizing:border-box}a.sidebar-link.active,a.sidebar-link:hover{--text-opacity:1;color:#805ad5;color:rgba(128,90,213,var(--text-opacity))}a.sidebar-link.active{font-weight:600;--border-opacity:1;border-color:#805ad5;border-color:rgba(128,90,213,var(--border-opacity))}.sidebar-group a.sidebar-link{padding-left:2rem}.sidebar-sub-headers a.sidebar-link{padding-top:.25rem;padding-bottom:.25rem;border-left:none}.sidebar-sub-headers a.sidebar-link.active{font-weight:500}.sidebar-group .sidebar-group{padding-left:.5em}.sidebar-group:not(.collapsable) .sidebar-heading:not(.clickable){cursor:auto;color:inherit}.sidebar-group.is-sub-group{padding-left:0}.sidebar-group.is-sub-group>.sidebar-heading{font-size:.95em;line-height:1.4;font-weight:400;padding-left:2rem}.sidebar-group.is-sub-group>.sidebar-heading:not(.clickable){opacity:.5}.sidebar-group.is-sub-group>.sidebar-group-items{padding-left:1rem}.sidebar-group.is-sub-group>.sidebar-group-items>li>.sidebar-link{font-size:.95em;border-left:none}.sidebar-group.depth-2>.sidebar-heading{border-left:none}.sidebar-heading{color:#2c3e50;transition:color .15s ease;cursor:pointer;font-size:1.1em;font-weight:700;padding:.35rem 1.5rem .35rem 1.25rem;width:100%;box-sizing:border-box;margin:0;border-left:.25rem solid transparent}.sidebar-heading.open,.sidebar-heading:hover{color:inherit}.sidebar-heading .arrow{position:relative;top:-.12em;left:.5em;border-left:6px solid #ccc;border-top:4px solid transparent;border-bottom:4px solid transparent;transition:all .2s ease;transform:rotate(0)}.sidebar-heading .arrow.open{transform:rotate(90deg);top:-.05em}.sidebar-heading.clickable.active{font-weight:600;color:#553c9a;border-left-color:#553c9a}.sidebar-heading.clickable:hover{color:#553c9a}.sidebar-group-items{transition:height .1s ease-out;font-size:.95em;overflow:hidden}.sidebar[data-v-a68ca4e6]::-webkit-scrollbar-track{-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,.3);border-radius:10px;background-color:#f5f5f5}.sidebar[data-v-a68ca4e6]::-webkit-scrollbar{width:12px;background-color:#f5f5f5}.sidebar[data-v-a68ca4e6]::-webkit-scrollbar-thumb{border-radius:10px;-webkit-box-shadow:inset 0 0 6px rgba(0,0,0,.3);background-color:#555}.sidebar{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.sidebar .active{--text-opacity:1;color:#3182ce;color:rgba(49,130,206,var(--text-opacity))}.sidebar ul{padding:0;margin:0;list-style-type:none}.sidebar a{display:inline-block}.sidebar .nav-links{display:none;border-bottom:1px solid #eaecef;padding:4rem 0 .75rem}.sidebar .nav-links a{font-weight:600}.sidebar .nav-links .nav-item,.sidebar .nav-links .repo-link{display:block;line-height:1.25rem;font-size:1.1em;padding:.5rem 0 .5rem 1.5rem}.sidebar>.sidebar-links{padding:1.5rem 0}.sidebar>.sidebar-links>li>a.sidebar-link{font-size:1.1em;line-height:1.7;font-weight:700}.sidebar>.sidebar-links>li:not(:first-child){margin-top:.75rem}@media (max-width:719px){.sidebar .nav-links{display:block}.sidebar .nav-links .dropdown-wrapper .nav-dropdown .dropdown-item a.router-link-active:after{top:calc(1rem - 2px)}.sidebar>.sidebar-links{padding:1rem 0}}.sub-bar{height:3.6rem;position:fixed;top:3.6rem;background:#171717;width:100%;z-index:19}.sub-bar .message{margin:0 auto;display:flex;justify-content:center;align-items:center;height:100%;text-align:center}.sub-bar .message a{color:#e5e5e5;font-weight:600}.sectionLayout .content img{width:100%;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}@media (max-width:767px){.sectionLayout .content li{word-break:break-word}}.theme-container[data-v-24c39123]{--bg-opacity:1;background-color:#f7fafc;background-color:rgba(247,250,252,var(--bg-opacity))}.sidebar[data-v-24c39123]{position:fixed;top:80px;left:auto;bottom:0;right:0;border-radius:.25rem;--bg-opacity:1;background-color:#edf2f7;background-color:rgba(237,242,247,var(--bg-opacity))}.sidebar div[data-v-24c39123]{padding:1rem 2rem}.hero[data-v-24c39123]{height:400px;--bg-opacity:1;background-color:#e9d8fd;background-color:rgba(233,216,253,var(--bg-opacity));--border-opacity:1;border-color:#f7fafc;border-left-color:rgba(247,250,252,var(--border-opacity));border-bottom:5px dashed;border-bottom-color:rgba(247,250,252,var(--border-opacity));border-right-color:rgba(247,250,252,var(--border-opacity));border-top-color:rgba(247,250,252,var(--border-opacity));background:url(/img/back.png) #805ad5}.container[data-v-24c39123]{max-width:860px;margin:5rem auto 2.5rem}.container .content[data-v-24c39123]{background:#fff;margin-top:-370px;z-index:100;padding:2rem;border-radius:.5rem}.container img[data-v-24c39123]{width:100%;box-shadow:0 1px 3px 0 rgba(0,0,0,.1),0 1px 2px 0 rgba(0,0,0,.06)}@media(max-width:600px){.hero[data-v-24c39123]{display:none}.container[data-v-24c39123]{padding-left:0;padding-right:0;font-size:.875rem;width:100%;padding-left:0!important;padding-right:0!important}.container .content[data-v-24c39123]{padding-left:1rem;padding-right:1rem;margin-top:0}}@media(max-width:1100px){.hero[data-v-24c39123]{display:none}.container[data-v-24c39123]{padding-left:1rem;padding-right:1rem}.container .content[data-v-24c39123]{margin-top:0}}@media(max-width:1550px){.sidebar[data-v-24c39123]{top:0;left:0;transform:translateX(-100%)}}@media(max-width:1350px){.container[data-v-24c39123]{padding-left:1rem;padding-right:1rem}} \ No newline at end of file diff --git a/assets/img/search.83621669.svg b/assets/img/search.83621669.svg new file mode 100644 index 00000000..03d83913 --- /dev/null +++ b/assets/img/search.83621669.svg @@ -0,0 +1 @@ + diff --git a/assets/js/1.c70685ea.js b/assets/js/1.c70685ea.js new file mode 100644 index 00000000..c381504a --- /dev/null +++ b/assets/js/1.c70685ea.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[1,14,15,16,20,21,24,27],{239:function(t,e,n){"use strict";n.d(e,"d",(function(){return s})),n.d(e,"a",(function(){return r})),n.d(e,"i",(function(){return o})),n.d(e,"f",(function(){return l})),n.d(e,"g",(function(){return u})),n.d(e,"h",(function(){return c})),n.d(e,"b",(function(){return h})),n.d(e,"e",(function(){return f})),n.d(e,"k",(function(){return p})),n.d(e,"l",(function(){return d})),n.d(e,"c",(function(){return g})),n.d(e,"j",(function(){return m}));n(89);const s=/#.*$/,i=/\.(md|html)$/,r=/\/$/,o=/^[a-z]+:/i;function a(t){return decodeURI(t).replace(s,"").replace(i,"")}function l(t){return o.test(t)}function u(t){return/^mailto:/.test(t)}function c(t){return/^tel:/.test(t)}function h(t){if(l(t))return t;const e=t.match(s),n=e?e[0]:"",i=a(t);return r.test(i)?t:i+".html"+n}function f(t,e){const n=t.hash,i=function(t){const e=t.match(s);if(e)return e[0]}(e);if(i&&n!==i)return!1;return a(t.path)===a(e)}function p(t,e,n){if(l(e))return{type:"external",path:e};n&&(e=function(t,e,n){const s=t.charAt(0);if("/"===s)return t;if("?"===s||"#"===s)return e+t;const i=e.split("/");n&&i[i.length-1]||i.pop();const r=t.replace(/^\//,"").split("/");for(let t=0;t({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}(t);const a=o.sidebar||r.sidebar;if(a){const{base:t,config:n}=function(t,e){if(Array.isArray(e))return{base:"/",config:e};for(const s in e)if(0===(n=t,/(\.html|\/)$/.test(n)?n:n+"/").indexOf(encodeURI(s)))return{base:s,config:e[s]};var n;return{}}(e,a);return n?n.map(e=>function t(e,n,s,i=1){if("string"==typeof e)return p(n,e,s);if(Array.isArray(e))return Object.assign(p(n,e[0],s),{title:e[1]});{i>3&&console.error("[vuepress] detected a too deep nested sidebar group.");const r=e.children||[];return 0===r.length&&e.path?Object.assign(p(n,e.path,s),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,children:r.map(e=>t(e,n,s,i+1)),collapsable:!1!==e.collapsable}}}(e,i,t)):[]}return[]}function g(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function m(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},240:function(t,e,n){},241:function(t,e,n){},249:function(t,e,n){"use strict";n.r(e);var s={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},i=(n(253),n(14)),r=Object(i.a)(s,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=r.exports},250:function(t,e,n){"use strict";n.r(e);var s=n(239),i={props:{item:{required:!0}},computed:{link(){return Object(s.b)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link}},methods:{isExternal:s.f,isMailto:s.g,isTel:s.h,focusoutAction(){this.$emit("focusout")}}},r=(n(252),n(14)),o=Object(r.a)(i,(function(){var t=this,e=t._self._c;return t.isExternal(t.link)?e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.isMailto(t.link)||t.isTel(t.link)?null:"_blank",rel:t.isMailto(t.link)||t.isTel(t.link)?null:"noopener noreferrer"},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),e("OutboundLink")],1):e("router-link",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v(t._s(t.item.text))])}),[],!1,null,"34dbfd23",null);e.default=o.exports},252:function(t,e,n){"use strict";n(240)},253:function(t,e,n){"use strict";n(241)},254:function(t,e,n){},271:function(t,e,n){},276:function(t,e,n){"use strict";n(254)},281:function(t,e,n){"use strict";n.r(e);var s=n(282),i=n(239),r={components:{NavLink:n(250).default,DropdownLink:s.default},computed:{userNav(){return this.$themeLocaleConfig.nav||this.$site.themeConfig.nav||[]},nav(){const{locales:t}=this.$site;if(t&&Object.keys(t).length>1){const e=this.$page.path,n=this.$router.options.routes,s=this.$site.themeConfig.locales||{},i={text:this.$themeLocaleConfig.selectText||"Languages",ariaLabel:this.$themeLocaleConfig.ariaLabel||"Select language",items:Object.keys(t).map(i=>{const r=t[i],o=s[i]&&s[i].label||r.lang;let a;return r.lang===this.$lang?a=e:(a=e.replace(this.$localeConfig.path,i),n.some(t=>t.path===a)||(a=i)),{text:o,link:a}})};return[...this.userNav,i]}return this.userNav},userLinks(){return(this.nav||[]).map(t=>Object.assign(Object(i.j)(t),{items:(t.items||[]).map(i.j)}))},repoLink(){const{repo:t}=this.$site.themeConfig;return t?/^https?:/.test(t)?t:"https://github.com/"+t:null},repoLabel(){if(!this.repoLink)return;if(this.$site.themeConfig.repoLabel)return this.$site.themeConfig.repoLabel;const t=this.repoLink.match(/^https?:\/\/[^/]+/)[0],e=["GitHub","GitLab","Bitbucket"];for(let n=0;n({open:!1}),props:{item:{required:!0}},computed:{dropdownAriaLabel(){return this.item.ariaLabel||this.item.text}},methods:{toggle(){this.open=!this.open},isLastItemOfArray:(t,e)=>o()(e)===t},watch:{$route(){this.open=!1}}},l=(n(276),n(14)),u=Object(l.a)(a,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"dropdown-wrapper",class:{open:t.open}},[e("button",{staticClass:"dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:t.toggle}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow",class:t.open?"down":"right"})]),t._v(" "),e("DropdownTransition",[e("ul",{directives:[{name:"show",rawName:"v-show",value:t.open,expression:"open"}],staticClass:"nav-dropdown"},t._l(t.item.items,(function(n,s){return e("li",{key:n.link||s,staticClass:"dropdown-item"},["links"===n.type?e("div",{staticClass:"dropdown-item-title"},[t._v(t._s(n.text))]):t._e(),t._v(" "),"links"===n.type?e("ul",{staticClass:"dropdown-subitem-wrapper"},t._l(n.items,(function(s){return e("li",{key:s.link,staticClass:"dropdown-subitem"},[e("NavLink",{attrs:{item:s},on:{focusout:function(e){t.isLastItemOfArray(s,n.items)&&t.isLastItemOfArray(n,t.item.items)&&t.toggle()}}})],1)})),0):e("NavLink",{attrs:{item:n},on:{focusout:function(e){t.isLastItemOfArray(n,t.item.items)&&t.toggle()}}})],1)})),0)])],1)}),[],!1,null,null,null);e.default=u.exports},286:function(t,e,n){"use strict";var s=TypeError;t.exports=function(t,e){if(t{let s=r()(e,"title","");return r()(e,"frontmatter.tags")&&(s+=" "+e.frontmatter.tags.join(" ")),n&&(s+=" "+n),a(t,s)};const a=(t,e)=>{const n=t=>t.replace(/[-/\\^$*+?.()|[\]{}]/g,"\\$&"),s=new RegExp("[^\0-]"),i=t.split(/\s+/g).map(t=>t.trim()).filter(t=>!!t);if(s.test(t))return i.some(t=>e.toLowerCase().indexOf(t)>-1);{const s=t.endsWith(" ");return new RegExp(i.map((t,e)=>i.length!==e+1||s?`(?=.*\\b${n(t)}\\b)`:`(?=.*\\b${n(t)})`).join("")+".+","gi").test(e)}};var l={name:"SearchBox",data:()=>({query:"",focused:!1,focusIndex:0,placeholder:void 0}),computed:{showSuggestions(){return this.focused&&this.suggestions&&this.suggestions.length},suggestions(){const t=this.query.trim().toLowerCase();if(!t)return;const{pages:e}=this.$site,n=this.$site.themeConfig.searchMaxSuggestions||5,s=this.$localePath,i=[];for(let r=0;r=n);r++){const a=e[r];if(this.getPageLocalePath(a)===s&&this.isSearchable(a))if(o(t,a))i.push(a);else if(a.headers)for(let e=0;e=n);e++){const n=a.headers[e];n.title&&o(t,a,n.title)&&i.push(Object.assign({},a,{path:a.path+"#"+n.slug,header:n}))}}return i},alignRight(){return(this.$site.themeConfig.nav||[]).length+(this.$site.repo?1:0)<=2}},mounted(){this.placeholder=this.$site.themeConfig.searchPlaceholder||"",document.addEventListener("keydown",this.onHotkey)},beforeDestroy(){document.removeEventListener("keydown",this.onHotkey)},methods:{getPageLocalePath(t){for(const e in this.$site.locales||{})if("/"!==e&&0===t.path.indexOf(e))return e;return"/"},isSearchable(t){let e=null;return null===e||(e=Array.isArray(e)?e:new Array(e),e.filter(e=>t.path.match(e)).length>0)},onHotkey(t){t.srcElement===document.body&&["s","/"].includes(t.key)&&(this.$refs.input.focus(),t.preventDefault())},onUp(){this.showSuggestions&&(this.focusIndex>0?this.focusIndex--:this.focusIndex=this.suggestions.length-1)},onDown(){this.showSuggestions&&(this.focusIndex "+t._s(n.header.title))]):t._e()])])})),0):t._e()])}),[],!1,null,null,null).exports,h=n(315),f=n(281);function p(t,e){return t.ownerDocument.defaultView.getComputedStyle(t,null)[e]}var d={components:{SidebarButton:h.default,NavLinks:f.default,SearchBox:c,AlgoliaSearchBox:s.default},data:()=>({linksWrapMaxWidth:null}),mounted(){const t=parseInt(p(this.$el,"paddingLeft"))+parseInt(p(this.$el,"paddingRight"));(()=>{document.documentElement.clientWidth<719?this.linksWrapMaxWidth=null:this.linksWrapMaxWidth=this.$el.offsetWidth-t-(this.$refs.siteName&&this.$refs.siteName.offsetWidth||0)})()},computed:{algolia(){return this.$themeLocaleConfig.algolia||this.$site.themeConfig.algolia||{}},isAlgoliaSearch(){return this.algolia&&this.algolia.apiKey&&this.algolia.indexName}}},g=(n(319),n(320),Object(u.a)(d,(function(){var t=this,e=t._self._c;return e("header",{staticClass:"navbar"},[e("SidebarButton",{on:{"toggle-sidebar":function(e){return t.$emit("toggle-sidebar")}}}),t._v(" "),e("router-link",{staticClass:"home-link",attrs:{to:t.$localePath}},[t.$site.themeConfig.logo?e("img",{staticClass:"logo",attrs:{src:t.$withBase(t.$site.themeConfig.logo),alt:t.$siteTitle}}):t._e(),t._v(" "),t.$siteTitle?e("span",{ref:"siteName",staticClass:"site-name",class:{"can-hide":t.$site.themeConfig.logo}},[t._v(t._s(t.$siteTitle))]):t._e()]),t._v(" "),e("div",{staticClass:"links",style:t.linksWrapMaxWidth?{"max-width":t.linksWrapMaxWidth+"px"}:{}},[e("a",{staticClass:"can-hide",attrs:{target:"_blank",rel:"nofollow",href:"https://opencollective.com/codeceptjs"}},[t._v("💖 Support Us")]),t._v("    \n "),t.isAlgoliaSearch?e("AlgoliaSearchBox",{attrs:{options:t.algolia}}):!1!==t.$site.themeConfig.search&&!1!==t.$page.frontmatter.search?e("SearchBox"):t._e(),t._v(" "),e("NavLinks",{staticClass:"can-hide"})],1)],1)}),[],!1,null,null,null));e.default=g.exports},306:function(t,e,n){},307:function(t,e,n){},308:function(t,e,n){},312:function(t,e,n){"use strict";n.r(e);n(89),n(294),n(295),n(296);var s={props:["options"],data:()=>({placeholder:void 0}),mounted(){this.initialize(this.options,this.$lang),this.placeholder=this.$site.themeConfig.searchPlaceholder||""},methods:{initialize(t,e){Promise.all([Promise.all([n.e(0),n.e(11)]).then(n.t.bind(null,324,7)),Promise.all([n.e(0),n.e(11)]).then(n.t.bind(null,325,7))]).then(([n])=>{n=n.default;const{algoliaOptions:s={}}=t;n(Object.assign({},t,{inputSelector:"#algolia-search-input",algoliaOptions:Object.assign({facetFilters:["lang:"+e].concat(s.facetFilters||[])},s),handleSelected:(t,e,n)=>{const{pathname:s,hash:i}=new URL(n.url);this.$router.push(`${s}${i}`)}}))})},update(t,e){this.$el.innerHTML='',this.initialize(t,e)}},watch:{$lang(t){this.update(this.options,t)},options(t){this.update(t,this.$lang)}}},i=(n(298),n(14)),r=Object(i.a)(s,(function(){var t=this._self._c;return t("form",{staticClass:"algolia-search-wrapper search-box",attrs:{id:"search-form",role:"search"}},[t("input",{staticClass:"search-query",attrs:{id:"algolia-search-input",placeholder:this.placeholder}})])}),[],!1,null,null,null);e.default=r.exports},315:function(t,e,n){"use strict";n.r(e);n(301);var s=n(14),i=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"sidebar-button",on:{click:function(e){return t.$emit("toggle-sidebar")}}},[e("svg",{staticClass:"icon",attrs:{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",viewBox:"0 0 448 512"}},[e("path",{attrs:{fill:"#fff",d:"M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"}})])])}),[],!1,null,null,null);e.default=i.exports},318:function(t,e,n){"use strict";n(306)},319:function(t,e,n){"use strict";n(307)},320:function(t,e,n){"use strict";n(308)}}]); \ No newline at end of file diff --git a/assets/js/100.f0f6e8ec.js b/assets/js/100.f0f6e8ec.js new file mode 100644 index 00000000..eacb86ca --- /dev/null +++ b/assets/js/100.f0f6e8ec.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[100],{401:function(t,e,s){"use strict";s.r(e);var a=s(14),n=Object(a.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"vue-cli-plugin-e2e-codeceptjs"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#vue-cli-plugin-e2e-codeceptjs"}},[t._v("#")]),t._v(" vue-cli-plugin-e2e-codeceptjs")]),t._v(" "),e("p",[e("em",[t._v("Hey, how about some end 2 end testing for your Vue apps?")]),t._v(" 🤔")]),t._v(" "),e("p",[e("em",[t._v("Let's do it together! Vue, me, "),e("a",{attrs:{href:"https://codecept.io",target:"_blank",rel:"noopener noreferrer"}},[t._v("CodeceptJS"),e("OutboundLink")],1),t._v(" & "),e("a",{attrs:{href:"https://pptr.dev",target:"_blank",rel:"noopener noreferrer"}},[t._v("Puppeteer"),e("OutboundLink")],1),t._v(".")]),t._v(" 🤗")]),t._v(" "),e("p",[e("em",[t._v("Browser testing was never that simple. Just see it!")]),t._v(" 😍")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'My Component Button'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'My Component'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("say")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I am happy!'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// that's right, this is a valid test!")]),t._v("\n")])])]),e("h2",{attrs:{id:"how-to-try-it"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#how-to-try-it"}},[t._v("#")]),t._v(" How to try it?")]),t._v(" "),e("p",[e("strong",[t._v("Requirements:")])]),t._v(" "),e("ul",[e("li",[t._v("NodeJS >= 8.9")]),t._v(" "),e("li",[t._v("NPM / Yarn")]),t._v(" "),e("li",[t._v("Vue CLI installed globally")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("npm i vue-cli-plugin-codeceptjs-puppeteer --save-dev\n")])])]),e("p",[t._v("This will install CodeceptJS, CodeceptUI & Puppeteer with Chrome browser.")]),t._v(" "),e("p",[t._v("To add CodeceptJS to your project invoke installer:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("vue invoke vue-cli-plugin-codeceptjs-puppeteer\n")])])]),e("blockquote",[e("p",[t._v("You will be asked about installing a demo component. If you start a fresh project "),e("strong",[t._v("it is recommended to agree and install a demo component")]),t._v(", so you could see tests passing.")])]),t._v(" "),e("h2",{attrs:{id:"running-tests"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#running-tests"}},[t._v("#")]),t._v(" Running Tests")]),t._v(" "),e("p",[t._v("We added npm scripts:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("test:e2e")]),t._v(" - will execute tests with browser opened. If you installed test component, and started a test server, running this command will show you a brower window passed test.\n"),e("ul",[e("li",[t._v("Use "),e("code",[t._v("--headless")]),t._v(" option to run browser headlessly")]),t._v(" "),e("li",[t._v("Use "),e("code",[t._v("--serve")]),t._v(" option to start a dev server before tests")])])])]),t._v(" "),e("p",[t._v("Examples:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("npm run test:e2e\nnpm run test:e2e -- --headless\nnpm run test:e2e -- --serve\n")])])]),e("blockquote",[e("p",[t._v("This command is a wrapper for "),e("code",[t._v("codecept run --steps")]),t._v(". You can use the "),e("a",{attrs:{href:"/commands#run"}},[t._v("Run arguments and options")]),t._v(" here.")])]),t._v(" "),e("ul",[e("li",[e("code",[t._v("test:e2e:parallel")]),t._v(" - will execute tests headlessly in parallel processes (workers). By default runs tests in 2 workers.\n"),e("ul",[e("li",[t._v("Use an argument to set number of workers")]),t._v(" "),e("li",[t._v("Use "),e("code",[t._v("--serve")]),t._v(" option to start dev server before running")])])])]),t._v(" "),e("p",[t._v("Examples:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("npm run test:e2e:parallel\nnpm run test:e2e:parallel -- 3\nnpm run test:e2e:parallel -- 3 --serve\n")])])]),e("blockquote",[e("p",[t._v("This command is a wrapper for "),e("code",[t._v("codecept run-workers 2")]),t._v(". You can use the "),e("a",{attrs:{href:"/commands#run-workers"}},[t._v("Run arguments and options")]),t._v(" here.")])]),t._v(" "),e("ul",[e("li",[e("code",[t._v("test:e2e:open")]),t._v(" - this opens interactive web test runner. So you could see, review & run your tests from a browser.")])]),t._v(" "),e("p",[e("img",{attrs:{src:"https://user-images.githubusercontent.com/220264/70399222-b7a1bc00-1a2a-11ea-8f0b-2878b0328161.gif",alt:""}})]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("npm run test:e2e:open\n")])])]),e("h2",{attrs:{id:"directory-structure"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#directory-structure"}},[t._v("#")]),t._v(" Directory Structure")]),t._v(" "),e("p",[t._v("Generator has created these files:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[t._v("codecept"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("conf"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("js 👈 codeceptjs config\njsconfig"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("json 👈 enabling type definitons\ntests\n├── e2e\n│ ├── app_test"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("js 👈 demo test"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" edit it"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("\n│ ├── output 👈 temp directory "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" screenshots"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" reports"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" etc\n│ └── support\n│ └── steps_file"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("js 👈 common steps\n└── steps"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("d"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("ts 👈 type definitions\n")])])]),e("p",[t._v("If you agreed to create a demo component, you will also see "),e("code",[t._v("TestMe")]),t._v(" component in "),e("code",[t._v("src/components")]),t._v(" folder.")]),t._v(" "),e("h2",{attrs:{id:"locators"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#locators"}},[t._v("#")]),t._v(" Locators")]),t._v(" "),e("p",[t._v("For Vue apps a special "),e("code",[t._v("vue")]),t._v(" locator is available. It allows to select an element by its component name, and props.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("vue")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'MyComponent'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("vue")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Button'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("props")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("title")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Click Me'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("With Playwright, you can use Vue locators in any method where locator is required:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("vue")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Tab'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("props")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("title")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Click Me!'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("vue")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'t'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("props")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("title")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Clicked'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("To find Vue element names and props in a tree use "),e("a",{attrs:{href:"https://chromewebstore.google.com/detail/vuejs-devtools/nhdogjmejiglipccpnnnanhbledajbpd",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vue DevTools"),e("OutboundLink")],1),t._v(" extension.")]),t._v(" "),e("blockquote",[e("p",[t._v("Turn off minification for application builds otherwise component names will be uglified as well")])]),t._v(" "),e("p",[t._v("Vue locators work via "),e("a",{attrs:{href:"https://playwright.dev/docs/other-locators#vue-locator",target:"_blank",rel:"noopener noreferrer"}},[t._v("Playwright Vue Locator"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("h2",{attrs:{id:"how-to-write-tests"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#how-to-write-tests"}},[t._v("#")]),t._v(" How to write tests?")]),t._v(" "),e("ul",[e("li",[t._v("Open "),e("code",[t._v("tests/e2e/app_js")]),t._v(" and see the demo test")]),t._v(" "),e("li",[t._v("Execute a test & use interactive pause to see how CodeceptJS works")]),t._v(" "),e("li",[e("a",{attrs:{href:"/basics"}},[t._v("Learn CodeceptJS basics")])]),t._v(" "),e("li",[e("a",{attrs:{href:"/puppeteer"}},[t._v("Learn how to write CodeceptJS tests with Puppeteer")])]),t._v(" "),e("li",[e("a",{attrs:{href:"/helpers/Puppeteer"}},[t._v("See full reference for CodeceptJS Puppeteer Helper")])]),t._v(" "),e("li",[t._v("Ask your questions in "),e("a",{attrs:{href:"https://bit.ly/chat-codeceptjs",target:"_blank",rel:"noopener noreferrer"}},[t._v("Slack"),e("OutboundLink")],1),t._v(" & "),e("a",{attrs:{href:"https://codecept.discourse.group/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Forum"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"enjoy-testing"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#enjoy-testing"}},[t._v("#")]),t._v(" Enjoy testing!")]),t._v(" "),e("p",[t._v("Testing is simple & fun, enjoy it!")]),t._v(" "),e("p",[t._v("With ❤ "),e("a",{attrs:{href:"https://codecept.io",target:"_blank",rel:"noopener noreferrer"}},[t._v("CodeceptJS Team"),e("OutboundLink")],1)])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/101.ed2e0c48.js b/assets/js/101.ed2e0c48.js new file mode 100644 index 00000000..7428eb5a --- /dev/null +++ b/assets/js/101.ed2e0c48.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[101],{400:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"testing-with-webdriver"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#testing-with-webdriver"}},[t._v("#")]),t._v(" Testing with WebDriver")]),t._v(" "),s("p",[t._v("How does your client, manager, or tester, or any other non-technical person, know your web application is working? By opening the browser, accessing a site, clicking on links, filling in the forms, and actually seeing the content on a web page.")]),t._v(" "),s("p",[t._v("End-to-End tests can cover standard but complex scenarios from a user's perspective. With e2e tests you can be confident that users, following all defined scenarios, won't get errors. We check "),s("strong",[t._v("functionality of application and a user interface")]),t._v(" (UI) as well.")]),t._v(" "),s("h2",{attrs:{id:"what-is-selenium-webdriver"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#what-is-selenium-webdriver"}},[t._v("#")]),t._v(" What is Selenium WebDriver")]),t._v(" "),s("p",[t._v("The standard and proved way to run browser test automation over years is Selenium WebDriver. Over years this technology was standardized and works over all popular browsers and operating systems. There are cloud services like SauceLabs or BrowserStack which allow executing such browsers in the cloud. The superset of WebDriver protocol is also used to test "),s("a",{attrs:{href:"/mobile"}},[t._v("native and hybrid mobile applications")]),t._v(".")]),t._v(" "),s("p",[t._v("Let's clarify the terms:")]),t._v(" "),s("ul",[s("li",[t._v("Selenium - is a toolset for browser test automation")]),t._v(" "),s("li",[t._v("WebDriver - a standard protocol for communicating between test framework and browsers")]),t._v(" "),s("li",[t._v("JSON Wire - an older version of such protocol")])]),t._v(" "),s("p",[t._v("We use "),s("a",{attrs:{href:"https://webdriver.io",target:"_blank",rel:"noopener noreferrer"}},[t._v("webdriverio"),s("OutboundLink")],1),t._v(" library to run tests over WebDriver.")]),t._v(" "),s("p",[t._v("To proceed you need to have "),s("a",{attrs:{href:"/quickstart#using-selenium-webdriver"}},[t._v("CodeceptJS installed")]),t._v(" and "),s("code",[t._v("WebDriver")]),t._v(" helper selected.")]),t._v(" "),s("p",[t._v("Selenium WebDriver may be complicated from start, as it requires following tools to be installed and started.")]),t._v(" "),s("ol",[s("li",[t._v("Selenium Server - to execute and send commands to browser")]),t._v(" "),s("li",[t._v("ChromeDriver or GeckoDriver - to allow browsers to run in automated mode.")])]),t._v(" "),s("blockquote",[s("p",[t._v("Those tools can be easily installed via NPM. Use "),s("a",{attrs:{href:"https://www.npmjs.com/package/selenium-standalone",target:"_blank",rel:"noopener noreferrer"}},[t._v("selenium-standalone"),s("OutboundLink")],1),t._v(" to automatically install them.")])]),t._v(" "),s("p",[t._v("You can also use "),s("code",[t._v("@wdio/selenium-standalone-service")]),t._v(" package, to install and start Selenium Server for your tests automatically.")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npm i @wdio/selenium-standalone-service --save-dev\n")])])]),s("p",[t._v("Enable it in config inside plugins section:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v("exports"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside condecept.conf.js")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("plugins")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("wdio")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("enabled")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("services")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'selenium-standalone'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("⚠ It is not recommended to use wdio plugin & selenium-standalone when running tests in parallel. Consider "),s("strong",[t._v("switching to Selenoid")]),t._v(" if you need parallel run or using cloud services.")])]),t._v(" "),s("p",[t._v("🛩️ With the release of WebdriverIO version v8.14.0, and onwards, all driver management hassles are now a thing of the past 🙌. Read more "),s("a",{attrs:{href:"https://webdriver.io/blog/2023/07/31/driver-management/",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),s("OutboundLink")],1),t._v(".\nOne of the significant advantages of this update is that you can now get rid of any driver services you previously had to manage, such as\n"),s("code",[t._v("wdio-chromedriver-service")]),t._v(", "),s("code",[t._v("wdio-geckodriver-service")]),t._v(", "),s("code",[t._v("wdio-edgedriver-service")]),t._v(", "),s("code",[t._v("wdio-safaridriver-service")]),t._v(", and even "),s("code",[t._v("@wdio/selenium-standalone-service")]),t._v(".")]),t._v(" "),s("p",[t._v("For those who require custom driver options, fear not; WebDriver Helper allows you to pass in driver options through custom WebDriver configuration.\nIf you have a custom grid, use a cloud service, or prefer to run your own driver, there's no need to worry since WebDriver Helper will only start a driver when there are no other connection information settings like hostname or port specified.")]),t._v(" "),s("p",[t._v("Example:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("smartWait")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"chrome"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("restart")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("windowSize")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"maximize"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("timeouts")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"script"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("60000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"page load"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10000")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Testing Chrome locally is now more convenient than ever. You can define a browser channel, and WebDriver Helper will take care of downloading the specified browser version for you.\nFor example:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("smartWait")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"chrome"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browserVersion")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'116.0.5793.0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// or 'stable', 'beta', 'dev' or 'canary'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("restart")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("windowSize")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"maximize"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("timeouts")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"script"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("60000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"page load"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10000")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"configuring-webdriver"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#configuring-webdriver"}},[t._v("#")]),t._v(" Configuring WebDriver")]),t._v(" "),s("p",[t._v("WebDriver can be configured to run browser tests in window, headlessly, on a remote server or in a cloud.")]),t._v(" "),s("blockquote",[s("p",[t._v("By default, CodeceptJS is already configured to run WebDriver tests locally with Chrome or Firefox. If you just need to start running tests - proceed to the next chapter.")])]),t._v(" "),s("p",[t._v("Configuration for WebDriver should be provided inside "),s("code",[t._v("codecept.conf.(js|ts)")]),t._v(" file under "),s("code",[t._v("helpers: WebDriver")]),t._v(" section:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://myapp.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'chrome'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("host")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'127.0.0.1'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("port")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("4444")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("restart")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("windowSize")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1920x1680'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("desiredCapabilities")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("chromeOptions")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("args")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('/*"--headless",*/')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"--disable-gpu"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"--no-sandbox"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("By default, CodeceptJS runs tests in the same browser window but clears cookies and local storage after each test. This behavior can be changed with these options:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// change to true to restart browser between tests")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("restart")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// don't change browser state and not clear cookies between tests")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("keepBrowserState")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("keepCookies")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("▶ More config options available on "),s("a",{attrs:{href:"/helpers/WebDriver#configuration"}},[t._v("WebDriver helper reference")])])]),t._v(" "),s("h3",{attrs:{id:"chromedriver-without-selenium"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#chromedriver-without-selenium"}},[t._v("#")]),t._v(" ChromeDriver without Selenium")]),t._v(" "),s("p",[t._v("If you want to run tests using raw ChromeDriver (which also supports WebDriver protocol) avoiding Selenium Server, you should provide following configuration:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("port")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("9515")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'chrome'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("path")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("If you face issues connecting to WebDriver, please check that corresponding server is running on a specified port. If host is other than "),s("code",[t._v("localhost")]),t._v(" or port is other than "),s("code",[t._v("4444")]),t._v(", update the configuration.")])]),t._v(" "),s("h3",{attrs:{id:"selenium-in-docker-selenoid"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#selenium-in-docker-selenoid"}},[t._v("#")]),t._v(" Selenium in Docker (Selenoid)")]),t._v(" "),s("p",[t._v("Browsers can be executed in Docker containers. This is useful when testing on Continous Integration server.\nWe recommend using "),s("a",{attrs:{href:"https://aerokube.com/selenoid/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Selenoid"),s("OutboundLink")],1),t._v(" to run browsers in container.")]),t._v(" "),s("p",[t._v("CodeceptJS has "),s("a",{attrs:{href:"/plugins#selenoid"}},[t._v("Selenoid plugin")]),t._v(" which can automagically load browser container setup.")]),t._v(" "),s("h3",{attrs:{id:"headless-mode"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#headless-mode"}},[t._v("#")]),t._v(" Headless Mode")]),t._v(" "),s("p",[t._v("It is recommended to use "),s("code",[t._v("@codeceptjs/configure")]),t._v(" package to easily toggle headless mode for WebDriver:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside codecept.conf.js")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" setHeadlessWhen"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setWindowSize "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@codeceptjs/configure'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setHeadlessWhen")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("process"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("HEADLESS")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// enables headless mode when HEADLESS environment variable exists")]),t._v("\n")])])]),s("p",[t._v("This requires "),s("code",[t._v("@codeceptjs/configure")]),t._v(" package to be installed.")]),t._v(" "),s("p",[t._v("Alternatively, you can enable headless mode manually via desired capabilities.")]),t._v(" "),s("h3",{attrs:{id:"desired-capabilities"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#desired-capabilities"}},[t._v("#")]),t._v(" Desired Capabilities")]),t._v(" "),s("p",[t._v("Additional configuration can be passed via "),s("code",[t._v("desiredCapabilities")]),t._v(" option.\nFor instance, this is how we can set to "),s("strong",[t._v("run headless Chrome")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("desiredCapabilities")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("chromeOptions")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("args")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"--headless"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"--disable-gpu"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"--window-size=1200,1000"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"--no-sandbox"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Next popular use case for capabilities is configuring what to do with unhandled alert popups.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("desiredCapabilities")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// close all unexpected popups")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("unexpectedAlertBehaviour")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'dismiss'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"cloud-providers"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#cloud-providers"}},[t._v("#")]),t._v(" Cloud Providers")]),t._v(" "),s("p",[t._v("WebDriver protocol works over HTTP, so you need to have a Selenium Server to be running or any other service that will launch a browser for you. That's why you may need to specify "),s("code",[t._v("host")]),t._v(", "),s("code",[t._v("port")]),t._v(", "),s("code",[t._v("protocol")]),t._v(", and "),s("code",[t._v("path")]),t._v(" parameters.")]),t._v(" "),s("p",[t._v("By default, those parameters are set to connect to local Selenium Server, but they should be changed if you want to run tests via "),s("a",{attrs:{href:"/helpers/WebDriver#cloud-providers"}},[t._v("Cloud Providers")]),t._v(". You may also need "),s("code",[t._v("user")]),t._v(" and "),s("code",[t._v("key")]),t._v(" parameters to authenticate on cloud service.")]),t._v(" "),s("p",[t._v("There are also "),s("a",{attrs:{href:"https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities",target:"_blank",rel:"noopener noreferrer"}},[t._v("browser and platform specific capabilities"),s("OutboundLink")],1),t._v(". Services like SauceLabs, BrowserStack or browser vendors can provide their own specific capabilities for more tuning.")]),t._v(" "),s("p",[t._v("Here is a sample BrowserStack config for running tests on iOS mobile browser:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("host")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'hub.browserstack.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("path")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/wd/hub'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'http://WEBSITE:8080/renderer'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'xx'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// credentials")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("key")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'xx'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// credentials")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'iphone'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("desiredCapabilities")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'os_version'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'11'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'device'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'iPhone 8'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// you can select device")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'real_mobile'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'true'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// real or emulated")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'browserstack.local'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'true'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'browserstack.debug'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'true'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'browserstack.networkLogs'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'true'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'browserstack.appium_version'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1.9.1'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'browserstack.user'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'xx'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// credentials")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'browserstack.key'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'xx'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// credentials")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"writing-tests"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#writing-tests"}},[t._v("#")]),t._v(" Writing Tests")]),t._v(" "),s("p",[t._v("CodeceptJS provides high-level API on top of WebDriver protocol. While most standard implementations focus on dealing with WebElements on page, CodeceptJS is about user scenarios and interactions. That's why you don't have a direct access to web elements inside a test, but it is proved that in majority of cases you don't need it. Tests written from user's perspective are simpler to write, understand, log and debug.")]),t._v(" "),s("blockquote",[s("p",[t._v("If you come from Java, Python or Ruby don't be afraid of a new syntax. It is more flexible than you think!")])]),t._v(" "),s("p",[t._v("A typical test case may look like this:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'login test'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Username'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'123456'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Welcome, John'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("An empty test case can be created with "),s("code",[t._v("npx codeceptjs gt")]),t._v(" command.")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs gt\n")])])]),s("h3",{attrs:{id:"actions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#actions"}},[t._v("#")]),t._v(" Actions")]),t._v(" "),s("p",[t._v("Tests consist with a scenario of user's action taken on a page. The most widely used ones are:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("amOnPage")]),t._v(" - to open a webpage (accepts relative or absolute url)")]),t._v(" "),s("li",[s("code",[t._v("click")]),t._v(" - to locate a button or link and click on it")]),t._v(" "),s("li",[s("code",[t._v("fillField")]),t._v(" - to enter a text inside a field")]),t._v(" "),s("li",[s("code",[t._v("selectOption")]),t._v(", "),s("code",[t._v("checkOption")]),t._v(" - to interact with a form")]),t._v(" "),s("li",[s("code",[t._v("wait*")]),t._v(" to wait for some parts of page to be fully rendered (important for testing SPA)")]),t._v(" "),s("li",[s("code",[t._v("grab*")]),t._v(" to get values from page sources")]),t._v(" "),s("li",[s("code",[t._v("see")]),t._v(", "),s("code",[t._v("dontSee")]),t._v(" - to check for a text on a page")]),t._v(" "),s("li",[s("code",[t._v("seeElement")]),t._v(", "),s("code",[t._v("dontSeeElement")]),t._v(" - to check for elements on a page")])]),t._v(" "),s("blockquote",[s("p",[t._v("ℹ All actions are listed in "),s("a",{attrs:{href:"https://codecept.io/helpers/WebDriver/",target:"_blank",rel:"noopener noreferrer"}},[t._v("WebDriver helper reference"),s("OutboundLink")],1),t._v(".*")])]),t._v(" "),s("p",[t._v("All actions which interact with elements "),s("strong",[t._v("support CSS and XPath locators")]),t._v(". Actions like "),s("code",[t._v("click")]),t._v(" or "),s("code",[t._v("fillField")]),t._v(" by locate elements by their name or value on a page:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// search for link or button")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate field by its label")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Name'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Miles'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// we can use input name")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user[email]'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'miles@davis.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("You can also specify the exact locator type with strict locators:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("css")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'button.red'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user[email]'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'miles@davis.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("xpath")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'//body/header'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"interactive-pause"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#interactive-pause"}},[t._v("#")]),t._v(" Interactive Pause")]),t._v(" "),s("p",[t._v("It's easy to start writing a test if you use "),s("a",{attrs:{href:"/basics#debug"}},[t._v("interactive pause")]),t._v(". Just open a web page and pause execution.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Sample Test'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'open my website'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pause")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("This is just enough to run a test, open a browser, and think what to do next to write a test case.")]),t._v(" "),s("p",[t._v("When you execute such test with "),s("code",[t._v("npx codeceptjs run")]),t._v(" command you may see the browser is started")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run --steps\n")])])]),s("p",[t._v("After a page is opened a full control of a browser is given to a terminal. Type in different commands such as "),s("code",[t._v("click")]),t._v(", "),s("code",[t._v("see")]),t._v(", "),s("code",[t._v("fillField")]),t._v(" to write the test. A successful commands will be saved to "),s("code",[t._v("./output/cli-history")]),t._v(" file and can be copied into a test.")]),t._v(" "),s("blockquote",[s("p",[t._v("ℹ All actions are listed in "),s("a",{attrs:{href:"/helpers/WebDriver"}},[t._v("WebDriver helper reference")]),t._v(".")])]),t._v(" "),s("p",[t._v("An interactive shell output may look like this:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v(" Interactive shell started\n Use JavaScript syntax to try steps in action\n - Press ENTER to run the next step\n - Press TAB twice to see all available commands\n - Type exit + Enter to exit the interactive shell\n I.fillField('.new-todo', 'Write a test')\n I.pressKey('Enter')\n I.\n Commands have been saved to /home/davert/demos/codeceptjs/output/cli-history\n")])])]),s("p",[t._v("After typing in successful commands you can copy them into a test.")]),t._v(" "),s("p",[t._v("Here is a test checking basic "),s("a",{attrs:{href:"https://todomvc.com/",target:"_blank",rel:"noopener noreferrer"}},[t._v("todo application"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'TodoMVC'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'create todo item'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/examples/vue/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.new-todo'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.new-todo'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Write a test'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pressKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Enter'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1 item left'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.todo-count'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[s("a",{attrs:{href:"https://github.com/DavertMik/codeceptjs-webdriver-example",target:"_blank",rel:"noopener noreferrer"}},[t._v("▶ Working example of CodeceptJS WebDriver tests"),s("OutboundLink")],1),t._v(" for TodoMVC application.")])]),t._v(" "),s("p",[t._v("WebDriver helper supports standard "),s("a",{attrs:{href:"/locators"}},[t._v("CSS/XPath and text locators")]),t._v(" as well as non-trivial "),s("a",{attrs:{href:"/react"}},[t._v("React locators")]),t._v(" and "),s("a",{attrs:{href:"/shadow"}},[t._v("Shadow DOM")]),t._v(".")]),t._v(" "),s("h3",{attrs:{id:"grabbers"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#grabbers"}},[t._v("#")]),t._v(" Grabbers")]),t._v(" "),s("p",[t._v("If you need to get element's value inside a test you can use "),s("code",[t._v("grab*")]),t._v(" methods. They should be used with "),s("code",[t._v("await")]),t._v(" operator inside "),s("code",[t._v("async")]),t._v(" function:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" assert "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'assert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'get value of current tasks'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.todo'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'my first item'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pressKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Enter'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.todo'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'my second item'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pressKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Enter'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" numTodos "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabTextFrom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.todo-count strong'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" numTodos"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"within"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#within"}},[t._v("#")]),t._v(" Within")]),t._v(" "),s("p",[t._v("In case some actions should be taken inside one element (a container or modal window or iframe) you can use "),s("code",[t._v("within")]),t._v(" block to narrow the scope.\nPlease take a note that you can't use within inside another within in Puppeteer helper:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("within")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.todoapp'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.todo'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'my new item'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pressKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Enter'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1 item left'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.todo-count'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.todo-list input.toggle'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'0 items left'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.todo-count'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"each-element"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#each-element"}},[t._v("#")]),t._v(" Each Element "),s("Badge",{attrs:{text:"Since 3.3",type:"warning"}})],1),t._v(" "),s("p",[t._v("Usually, CodeceptJS performs an action on the first matched element.\nIn case you want to do an action on each element found, use the special function "),s("code",[t._v("eachElement")]),t._v(" which comes from "),s("a",{attrs:{href:"https://codecept.io/plugins/#eachelement",target:"_blank",rel:"noopener noreferrer"}},[t._v("eachElement"),s("OutboundLink")],1),t._v(" plugin.")]),t._v(" "),s("p",[s("code",[t._v("eachElement")]),t._v(" function matches all elements by locator and performs a callback on each of those element. A callback function receives element of webdriverio. "),s("code",[t._v("eachElement")]),t._v(" may perform arbitrary actions on a page, so the first argument should by a description of the actions performed. This description will be used for logging purposes.")]),t._v(" "),s("p",[t._v("Usage example")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("eachElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'click all checkboxes'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'input.custom-checkbox'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("el"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" index")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" el"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("ℹ Learn more about "),s("RouterLink",{attrs:{to:"/plugins/#eachelement"}},[t._v("eachElement plugin")])],1)]),t._v(" "),s("h2",{attrs:{id:"waiting"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#waiting"}},[t._v("#")]),t._v(" Waiting")]),t._v(" "),s("p",[t._v("Web applications do not always respond instantly. That's why WebDriver protocol has methods to wait for changes on a page. CodeceptJS provides such commands prefixed with "),s("code",[t._v("wait*")]),t._v(" so you could explicitly define what effects we wait for.")]),t._v(" "),s("p",[t._v('Most popular "waiters" are:')]),t._v(" "),s("ul",[s("li",[s("code",[t._v("waitForText")]),t._v(" - wait for text to appear on a page")]),t._v(" "),s("li",[s("code",[t._v("waitForElement")]),t._v(" - wait for element to appear on a page")]),t._v(" "),s("li",[s("code",[t._v("waitForInvisible")]),t._v(" - wait element to become invisible.")])]),t._v(" "),s("p",[t._v("By default, they will wait for 1 second. This number can be changed in WebDriver configuration:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside codecept.conf.js")]),t._v("\nexports"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// WebDriver config goes here")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// wait for 5 seconds")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("waitForTimeout")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5000")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"smartwait"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#smartwait"}},[t._v("#")]),t._v(" SmartWait")]),t._v(" "),s("p",[t._v("It is possible to wait for elements pragmatically. If a test uses element which is not on a page yet, CodeceptJS will wait for few extra seconds before failing. This feature is based on "),s("a",{attrs:{href:"https://www.seleniumhq.org/docs/04_webdriver_advanced.jsp#implicit-waits",target:"_blank",rel:"noopener noreferrer"}},[t._v("Implicit Wait"),s("OutboundLink")],1),t._v(" of Selenium. CodeceptJS enables implicit wait only when searching for a specific element and disables in all other cases. Thus, the performance of a test is not affected.")]),t._v(" "),s("p",[t._v("SmartWait can be enabled by setting wait option in WebDriver config.\nAdd "),s("code",[t._v("smartWait: 5000")]),t._v(" to wait for additional 5s.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside codecept.conf.js")]),t._v("\nexports"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// WebDriver config goes here")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// smart wait for 5 seconds")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("smartWait")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5000")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("SmartWait works with a CSS/XPath locators in "),s("code",[t._v("click")]),t._v(", "),s("code",[t._v("seeElement")]),t._v(" and other methods. See where it is enabled and where is not:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// DISABLED, not a locator")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// DISABLED, not a specific locator")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'123456'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ENABLED, strict locator")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ENABLED, locator is CSS ID")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello, Davert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// DISABLED, Not a locator")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#userbar'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ENABLED")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// DISABLED, can't wait for element to hide")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeNumberOfElements")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'button.link'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// DISABLED, can wait only for one element")]),t._v("\n\n")])])]),s("p",[t._v("SmartWait doesn't check element for visibility, so tests may fail even element is on a page.")]),t._v(" "),s("p",[t._v("Usage example:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// we use smartWait: 5000 instead of")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// I.waitForElement('#click-me', 5);")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// to wait for element on page")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#click-me'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("If it's hard to define what to wait, it is recommended to use "),s("RouterLink",{attrs:{to:"/basics/#retries"}},[t._v("retries")]),t._v(" to rerun flaky steps.")],1),t._v(" "),s("h2",{attrs:{id:"configuring-ci"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#configuring-ci"}},[t._v("#")]),t._v(" Configuring CI")]),t._v(" "),s("p",[t._v("To develop tests it's fine to use local Selenium Server and window mode. Setting up WebDriver on remote CI (Continous Integration) server is different. If there is no desktop and no window mode on CI.")]),t._v(" "),s("p",[t._v("There are following options available:")]),t._v(" "),s("ul",[s("li",[t._v("Use headless Chrome or Firefox.")]),t._v(" "),s("li",[t._v("Use "),s("a",{attrs:{href:"/plugins/selenoid"}},[t._v("Selenoid")]),t._v(" to run browsers inside Docker containers.")]),t._v(" "),s("li",[t._v("Use paid "),s("a",{attrs:{href:"/helpers/WebDriver#cloud-providers"}},[t._v("cloud services (SauceLabs, BrowserStack, TestingBot)")]),t._v(".")])]),t._v(" "),s("h2",{attrs:{id:"video-recording"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#video-recording"}},[t._v("#")]),t._v(" Video Recording")]),t._v(" "),s("p",[t._v("When "),s("a",{attrs:{href:"/plugins#selenoid"}},[t._v("Selenoid Plugin")]),t._v(" is enabled video can be automatically recorded for each test.")]),t._v(" "),s("h2",{attrs:{id:"auto-login"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#auto-login"}},[t._v("#")]),t._v(" Auto Login")]),t._v(" "),s("p",[t._v("To share the same user session across different tests CodeceptJS provides "),s("a",{attrs:{href:"/plugins#autologin"}},[t._v("autoLogin plugin")]),t._v(". It simplifies login management and reduces time consuming login operations. Instead of filling in login form before each test it saves the cookies of a valid user session and reuses it for next tests. If a session expires or doesn't exist, logs in a user again.")]),t._v(" "),s("p",[t._v("This plugin requires some configuration but is very simple in use:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'do something with logged in user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" login "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("login")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Dashboard'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'h1'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("With "),s("code",[t._v("autoLogin")]),t._v(" plugin you can save cookies into a file and reuse same session on different runs.")]),t._v(" "),s("blockquote",[s("p",[s("a",{attrs:{href:"/plugins#autologin"}},[t._v("▶ How to set up autoLogin plugin")])])]),t._v(" "),s("h2",{attrs:{id:"multiple-windows"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#multiple-windows"}},[t._v("#")]),t._v(" Multiple Windows")]),t._v(" "),s("p",[t._v("CodeceptJS allows to use several browser windows inside a test. Sometimes we are testing the functionality of websites that we cannot control, such as a closed-source managed package, and there are popups that either remain open for configuring data on the screen, or close as a result of clicking a window. We can use these functions in order to gain more control over which page is being tested with Codecept at any given time. For example:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" assert "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'assert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'should open main page of configured site, open a popup, switch to main page, then switch to popup, close popup, and go back to main page'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" handleBeforePopup "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabCurrentWindowHandle")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" urlBeforePopup "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabCurrentUrl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" allHandlesBeforePopup "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabAllWindowHandles")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("allHandlesBeforePopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Single Window'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("executeScript")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://www.w3schools.com/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'new window'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'toolbar=yes,scrollbars=yes,resizable=yes,width=400,height=400'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" allHandlesAfterPopup "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabAllWindowHandles")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("allHandlesAfterPopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Two Windows'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("switchToWindow")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("allHandlesAfterPopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" urlAfterPopup "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabCurrentUrl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("urlAfterPopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://www.w3schools.com/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Expected URL: Popup'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("handleBeforePopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" allHandlesAfterPopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Expected Window: Main Window'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("switchToWindow")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("handleBeforePopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" currentURL "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabCurrentUrl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("currentURL"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" urlBeforePopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Expected URL: Main URL'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("switchToWindow")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("allHandlesAfterPopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" urlAfterSwitchBack "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabCurrentUrl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("urlAfterSwitchBack"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://www.w3schools.com/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Expected URL: Popup'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("closeCurrentTab")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" allHandlesAfterPopupClosed "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabAllWindowHandles")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("allHandlesAfterPopupClosed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Single Window'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" currentWindowHandle "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabCurrentWindowHandle")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("currentWindowHandle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" allHandlesAfterPopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Expected Window: Main Window'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"mocking-requests"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#mocking-requests"}},[t._v("#")]),t._v(" Mocking Requests")]),t._v(" "),s("p",[t._v("When testing web application you can disable some of external requests calls by enabling HTTP mocking.\nThis is useful when you want to isolate application testing from a backend. For instance, if you don't want to save data to database, and you know the request which performs save, you can mock the request, so application will treat this as valid response, but no data will be actually saved.")]),t._v(" "),s("blockquote",[s("p",[s("strong",[t._v("WebDriver has limited ability to mock requests")]),t._v(", so you can only mock only requests performed after page is loaded. This means that you can't block Google Analytics, or CDN calls, but you can mock API requests performed on user action.")])]),t._v(" "),s("p",[t._v("To mock requests enable additional helper "),s("a",{attrs:{href:"/helpers/MockRequest"}},[t._v("MockRequest")]),t._v(" (which is based on Polly.js).")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// regular WebDriver config here")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("MockRequest")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("The function "),s("code",[t._v("mockRequest")]),t._v(" will be added to "),s("code",[t._v("I")]),t._v(" object. You can use it to explicitly define which requests to block and which response they should return instead:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// block all Google Analytics calls")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/google-analytics/*path'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// return an empty successful response")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'GET'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/users'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// block post requests to /api/users and return predefined object")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'POST'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/users'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// return error request with body")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'GET'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/users/1'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("404")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("error")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'User not found'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("In WebDriver mocking is disabled every time a new page is loaded. Hence, "),s("code",[t._v("startMocking")]),t._v(" method should be called and the mocks should be updated, after navigating to a new page. This is a limitation of WebDriver. Consider using Puppeteer with MockRequest instead.")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/xyz'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Go to Next Page'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// new page is loaded, mocking is disabled now. We need to set it up again")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// in WebDriver as we can't detect that the page was reloaded, so no mocking :(")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("See "),s("a",{attrs:{href:"/helpers/MockRequest#mockrequest"}},[s("code",[t._v("mockRequest")]),t._v(" API")])])]),t._v(" "),s("p",[t._v("To see "),s("code",[t._v("mockRequest")]),t._v(" method in intellisense auto completion don't forget to run "),s("code",[t._v("codeceptjs def")]),t._v(" command:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs def\n")])])]),s("p",[t._v("Mocking rules will be kept while a test is running. To stop mocking use "),s("code",[t._v("I.stopMocking()")]),t._v(" command")]),t._v(" "),s("h2",{attrs:{id:"accessing-webdriverio-api"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#accessing-webdriverio-api"}},[t._v("#")]),t._v(" Accessing webdriverio API")]),t._v(" "),s("p",[t._v("To get "),s("a",{attrs:{href:"https://webdriver.io/docs/api.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("webdriverio browser API"),s("OutboundLink")],1),t._v(" inside a test use "),s("RouterLink",{attrs:{to:"/helpers/WebDriver/#usewebdriverto"}},[s("code",[t._v("I.useWebDriverTo")])]),t._v(" method with a callback.\nTo keep test readable provide a description of a callback inside the first parameter.")],1),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useWebDriverTo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'do something with native webdriverio api'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" browser "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// use browser object here")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("webdriverio commands are asynchronous so a callback function must be async.")])]),t._v(" "),s("p",[t._v("WebDriver helper can be obtained in this function as well. Use this to get full access to webdriverio elements inside the test.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("useWebDriverTo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'click all Save buttons'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("WebDriver")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" els "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" WebDriver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("_locateClickable")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Save'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" el "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("of")]),t._v(" els"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" el"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"extending-webdriver"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#extending-webdriver"}},[t._v("#")]),t._v(" Extending WebDriver")]),t._v(" "),s("p",[t._v("CodeceptJS doesn't aim to embrace all possible functionality of WebDriver. At some points you may find that some actions do not exist, however it is easy to add one. You will need to use WebDriver API from "),s("a",{attrs:{href:"https://webdriver.io",target:"_blank",rel:"noopener noreferrer"}},[t._v("webdriver.io"),s("OutboundLink")],1),t._v(" library.")]),t._v(" "),s("p",[t._v("To create new actions which will be added into "),s("code",[t._v("I.")]),t._v(" object you need to create a new helper. This can be done with "),s("code",[t._v("codeceptjs gh")]),t._v(" command.")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs gh\n")])])]),s("p",[t._v('Name a new helper "Web". Now each method of a created class can be added to I object. Be sure to enable this helper in config:')]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v("exports"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/* WebDriver config goes here */")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebHelper")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// load custom helper")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./web_helper.js'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("ℹ See "),s("a",{attrs:{href:"/helpers"}},[t._v("Custom Helper")]),t._v(" guide to see more examples.")])]),t._v(" "),s("p",[t._v("While implementing custom actions using WebDriver API please note that, there is two versions of protocol: WebDriver and JSON Wire. Depending on a browser version one of those protocols can be used. We can't know for sure which protocol is going to used, so we will need to implement an action using both APIs.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" Helper "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" codeceptjs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helper"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Web")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Helper")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// method to drag an item to coordinates")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dragToPoint")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("el"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// access browser object from WebDriver")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" browser "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helpers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("WebDriver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("browser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helpers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("WebDriver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("moveCursorTo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("el"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("browser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("isW3C"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// we use WebDriver protocol")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" browser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("performActions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"pointerDown"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"button"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"pointerMove"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"origin"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"pointer"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"duration"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"pointerUp"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"button"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// we use JSON Wire protocol")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" browser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("buttonDown")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" browser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("moveToElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" x"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" browser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("buttonUp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// method which restarts browser")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("restartBrowser")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" browser "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helpers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("WebDriver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("browser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" browser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("reloadSession")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" browser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("maximizeWindow")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// method which goes to previous page")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("backToPreviousPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" browser "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helpers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("WebDriver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("browser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" browser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("back")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("When a helper is created, regenerate your step definitions, so you could see those actions when using "),s("a",{attrs:{href:"/basics#intellisense"}},[t._v("intellisense")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs def\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/102.3c1c8294.js b/assets/js/102.3c1c8294.js new file mode 100644 index 00000000..e7d21321 --- /dev/null +++ b/assets/js/102.3c1c8294.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[102],{403:function(e,t,n){"use strict";n.r(t);var o=n(14),r=Object(o.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h3",{attrs:{id:"practical-end-2-end-testing-with-codeceptjs"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#practical-end-2-end-testing-with-codeceptjs"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://leanpub.com/codeceptjs/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Practical End 2 End Testing with CodeceptJS"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("A book by "),t("strong",[e._v("Paul Vincent Beigang")])]),e._v(" "),t("p",[t("a",{attrs:{href:"https://leanpub.com/codeceptjs/",target:"_blank",rel:"noopener noreferrer"}},[t("img",{attrs:{src:"https://user-images.githubusercontent.com/220264/58870454-e2e8ce80-86c8-11e9-868e-7deefdde47ce.png",alt:""}}),t("OutboundLink")],1)]),e._v(" "),t("h4",{attrs:{id:"contents"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#contents"}},[e._v("#")]),e._v(" Contents:")]),e._v(" "),t("ol",[t("li",[e._v("Preparation for End 2 End Testing with CodeceptJS")]),e._v(" "),t("li",[e._v("Setup CodeceptJS with WebdriverIO")]),e._v(" "),t("li",[e._v("Create Your First CodeceptJS Test")]),e._v(" "),t("li",[e._v("Run Your First CodeceptJS Test Locally")]),e._v(" "),t("li",[e._v("Run Test on BrowserStack Against with the Safari Browser")]),e._v(" "),t("li",[e._v("How to Debug & Fix a Failing E2E Test")]),e._v(" "),t("li",[e._v("Run a CodeceptJS Test in GitLab´s Continuous Integration (CI) Environment")]),e._v(" "),t("li",[e._v("Delicious Test Reports With Allure")])]),e._v(" "),t("h3",{attrs:{id:"posts"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#posts"}},[e._v("#")]),e._v(" Posts")]),e._v(" "),t("p",[e._v("A list of good educational posts about CodeceptJS")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://medium.com/@dan.ryan.emmons/qa-automation-from-zero-to-hero-with-codeceptjs-end-to-end-testing-719db9d6ff5c",target:"_blank",rel:"noopener noreferrer"}},[e._v("QA Automation From Zero-to-Hero with CodeceptJS End-to-End Testing"),t("OutboundLink")],1),e._v(" by Dan Emmons")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://hackernoon.com/effective-end-2-end-testing-in-javascript-with-codeceptjs-37c8d7d6a928",target:"_blank",rel:"noopener noreferrer"}},[e._v("Effective End2End Tests with CodeceptJS"),t("OutboundLink")],1),e._v(" by @davertmik")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://medium.com/@successivetech/codeceptjs-skeleton-9ba86d3b45ec",target:"_blank",rel:"noopener noreferrer"}},[e._v("Customizing CodeceptJS Skeleton"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://hackernoon.com/running-end-to-end-tests-as-google-cloud-functions-f5e34ffc3984",target:"_blank",rel:"noopener noreferrer"}},[e._v("Running End to End tests as Google Cloud Functions"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.monterail.com/blog/end-to-end-testing-with-codeceptjs",target:"_blank",rel:"noopener noreferrer"}},[e._v("End-To-End Testing With CodeceptJS"),t("OutboundLink")],1),e._v(" by Piotr Michalski")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://medium.com/@garrettvorce/getting-started-with-selenium-and-codeceptjs-c0698e8df677",target:"_blank",rel:"noopener noreferrer"}},[e._v("Getting started with CodeceptJS and Selenium WebDriver"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);t.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/103.82fe6ad4.js b/assets/js/103.82fe6ad4.js new file mode 100644 index 00000000..13540ccc --- /dev/null +++ b/assets/js/103.82fe6ad4.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[103],{406:function(e,t,r){"use strict";r.r(t);var o=r(14),a=Object(o.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("Here is the list of helpers created by our community.\nPlease "),t("strong",[e._v("add your own")]),e._v(" by editing this page.")]),e._v(" "),t("h2",{attrs:{id:"webhooks"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#webhooks"}},[e._v("#")]),e._v(" Webhooks")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/onemolegames/codeceptjs-webhook-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-webhook-helper"),t("OutboundLink")],1),e._v(" - to check webhook calls during the tests.")])]),e._v(" "),t("h2",{attrs:{id:"email-checking"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#email-checking"}},[e._v("#")]),e._v(" Email Checking")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://gist.github.com/schmkr/026732dfa1627b927ff3a08dc31ee884",target:"_blank",rel:"noopener noreferrer"}},[e._v("MailCatcher"),t("OutboundLink")],1),e._v(" - to check emails via Mailcatcher locally.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/tsuemura/codeceptjs-mailhog-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-mailhog-helper"),t("OutboundLink")],1),e._v(" - to check emails via Mailhog locally.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/pavkam/codeceptjs-testmailapp-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-testmailapp-helper"),t("OutboundLink")],1),e._v(" - to check emails via Testmail.app service.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/yurkovychv/codeceptjs-mailosaur",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-mailosaurhelper"),t("OutboundLink")],1),e._v(" - to check emails via "),t("a",{attrs:{href:"https://mailosaur.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Mailosaur"),t("OutboundLink")],1),e._v(" service.")])]),e._v(" "),t("h2",{attrs:{id:"data-sources"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#data-sources"}},[e._v("#")]),e._v(" Data Sources")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/testphony/codeceptjs-httpMock",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-httpmock"),t("OutboundLink")],1),e._v(" - a helper which wraps mockttp library to manage http mock in tests.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/testphony/codeceptjs-http",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-http"),t("OutboundLink")],1),e._v(" - a helper which wraps then-request library to process HTTP requests. It's alternative helper that provides more flexible request management.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/thiagodp/codeceptjs-dbhelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-dbhelper"),t("OutboundLink")],1),e._v(" - allows you to execute queries or commands to databases using database-js.")])]),e._v(" "),t("h2",{attrs:{id:"cloud-providers"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#cloud-providers"}},[e._v("#")]),e._v(" Cloud Providers")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/puneet0191/codeceptjs-saucehelper/",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-saucehelper"),t("OutboundLink")],1),e._v(" - a helper which updates "),t("code",[e._v("Test Names")]),e._v(" & "),t("code",[e._v("Test Results")]),e._v(" on Saucelabs")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/PeterNgTr/codeceptjs-bshelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-bshelper"),t("OutboundLink")],1),e._v(" - a helper which updates "),t("code",[e._v("Test Names")]),e._v(" & "),t("code",[e._v("Test Results")]),e._v(" on Browserstack")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/testingbot/codeceptjs-tbhelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-tbhelper"),t("OutboundLink")],1),e._v(" - a helper which updates "),t("code",[e._v("Test Names")]),e._v(" & "),t("code",[e._v("Test Results")]),e._v(" on TestingBot")])]),e._v(" "),t("h2",{attrs:{id:"visual-testing"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#visual-testing"}},[e._v("#")]),e._v(" Visual-Testing")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/puneet0191/codeceptjs-resemblehelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-resemblehelper"),t("OutboundLink")],1),e._v(" - a helper which helps with visual testing using resemble.js.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.npmjs.com/package/codeceptjs-applitoolshelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-applitoolshelper"),t("OutboundLink")],1),e._v(" - a helper which helps interaction with "),t("a",{attrs:{href:"https://applitools.com",target:"_blank",rel:"noopener noreferrer"}},[e._v("Applitools"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/stracker-phil/codeceptjs-pixelmatchhelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-pixelmatchhelper"),t("OutboundLink")],1),e._v(" - a helper that integrates pixelmatch for visual testing.")])]),e._v(" "),t("h2",{attrs:{id:"reporters"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#reporters"}},[e._v("#")]),e._v(" Reporters")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/reportportal/agent-js-codecept",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-rphelper"),t("OutboundLink")],1),e._v(" is a CodeceptJS helper which can publish tests results on ReportPortal after execution.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.npmjs.com/package/codeceptjs-xray-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-xray-helper"),t("OutboundLink")],1),e._v(" is a CodeceptJS helper which can publish tests results on "),t("a",{attrs:{href:"https://confluence.xpand-it.com/display/XRAYCLOUD/Import+Execution+Results+-+REST",target:"_blank",rel:"noopener noreferrer"}},[e._v("XRAY"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.npmjs.com/package/codeceptjs-xray-cloud-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-xray-cloud-helper"),t("OutboundLink")],1),e._v(" is a helper that automatically retrieves the result of CodeceptJS tests and sends them to XRAY/JIRA(cloud version) via "),t("a",{attrs:{href:"https://docs.getxray.app/display/XRAYCLOUD/Import+Execution+Results+-+REST+v2#ImportExecutionResultsRESTv2-XrayJSONresults",target:"_blank",rel:"noopener noreferrer"}},[e._v("XRAY Cloud API"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.npmjs.com/package/codeceptjs-slack-reporter",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-slack-reporter"),t("OutboundLink")],1),e._v(" Get a Slack notification when one or more scenarios fail.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/pavkam/codeceptjs-browserlogs-plugin",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-browserlogs-plugin"),t("OutboundLink")],1),e._v(" Record the browser logs for failed tests.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/PeterNgTr/codeceptjs-testrail",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-testrail"),t("OutboundLink")],1),e._v(" - a plugin to integrate with "),t("a",{attrs:{href:"https://www.gurock.com/testrail",target:"_blank",rel:"noopener noreferrer"}},[e._v("Testrail"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/cenfun/codeceptjs-monocart-coverage",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-monocart-coverage"),t("OutboundLink")],1),e._v(" - a plugin to generate coverage reports, it integrate with "),t("a",{attrs:{href:"https://github.com/cenfun/monocart-coverage-reports",target:"_blank",rel:"noopener noreferrer"}},[e._v("monocart coverage reports"),t("OutboundLink")],1)])]),e._v(" "),t("h2",{attrs:{id:"browser-request-control"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#browser-request-control"}},[e._v("#")]),e._v(" Browser request control")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/luarmr/codeceptjs-resources-check",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-resources-check"),t("OutboundLink")],1),e._v(" Load a URL with Puppeteer and listen to the requests while the page is loading. Enabling count the number or check the sizes of the requests.")])]),e._v(" "),t("h2",{attrs:{id:"assertion-validations"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#assertion-validations"}},[e._v("#")]),e._v(" Assertion & Validations")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://www.npmjs.com/package/codeceptjs-chai",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-chai"),t("OutboundLink")],1),e._v(" is a CodeceptJS helper which wraps\n"),t("a",{attrs:{href:"https://www.chaijs.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("chai"),t("OutboundLink")],1),e._v(" library to complete chai assertion steps with CodeceptJS logging.")])]),e._v(" "),t("h2",{attrs:{id:"other"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#other"}},[e._v("#")]),e._v(" Other")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/thiagodp/codeceptjs-cmdhelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-cmdhelper"),t("OutboundLink")],1),e._v(" allows you to run commands in the terminal/console")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.npmjs.com/package/eslint-plugin-codeceptjs",target:"_blank",rel:"noopener noreferrer"}},[e._v("eslint-plugin-codeceptjs"),t("OutboundLink")],1),e._v(" Eslint rules for CodeceptJS.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/kobenguyent/codeceptjs-datalayer-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-datalayer-helper"),t("OutboundLink")],1),e._v(" CodeceptJS DataLayer helper helps you to get the datalayer JavaScript array that is used to store information and send this data to the tag manager.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/kobenguyent/codeceptjs-a11y-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-a11y-helper"),t("OutboundLink")],1),e._v(" accessibility tests integrated with CodeceptJS - Playwright-axe")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/kobenguyent/codeceptjs-lighthouse-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-lighthouse-helper"),t("OutboundLink")],1),e._v(" lighthouse audit integrated with CodeceptJS - Playwright")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.npmjs.com/package/@viasat/codeceptjs-snowplow-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("Snowplow Data analytics"),t("OutboundLink")],1),e._v(" - Test your Snowplow events implementations with CodeceptJS and Snowplow Micro.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/kobenguyent/codeceptjs-failure-logger",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-failure-logger"),t("OutboundLink")],1),e._v(" - Log failed CodeceptJS tests to file")])])])}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/104.e0cb470b.js b/assets/js/104.e0cb470b.js new file mode 100644 index 00000000..59eb84e7 --- /dev/null +++ b/assets/js/104.e0cb470b.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[104],{411:function(e,t,r){"use strict";r.r(t);var a=r(14),o=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("Here is the list of helpers created by our community.\nPlease "),t("strong",[e._v("add your own")]),e._v(" by editing this page.")]),e._v(" "),t("h2",{attrs:{id:"email-checking"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#email-checking"}},[e._v("#")]),e._v(" Email Checking")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://gist.github.com/schmkr/026732dfa1627b927ff3a08dc31ee884",target:"_blank",rel:"noopener noreferrer"}},[e._v("MailCatcher"),t("OutboundLink")],1),e._v(" - to check emails via Mailcatcher locally.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/tsuemura/codeceptjs-mailhog-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-mailhog-helper"),t("OutboundLink")],1),e._v(" - to check emails via Mailhog locally.")])]),e._v(" "),t("h2",{attrs:{id:"data-sources"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#data-sources"}},[e._v("#")]),e._v(" Data Sources")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/testphony/codeceptjs-httpMock",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-httpmock"),t("OutboundLink")],1),e._v(" - a helper which wraps mockttp library to manage http mock in tests.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/testphony/codeceptjs-http",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-http"),t("OutboundLink")],1),e._v(" - a helper which wraps then-request library to process HTTP requests. It's alternative helper that provides more flexible request management.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/thiagodp/codeceptjs-dbhelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-dbhelper"),t("OutboundLink")],1),e._v(" - allows you to execute queries or commands to databases using database-js.")])]),e._v(" "),t("h2",{attrs:{id:"cloud-providers"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#cloud-providers"}},[e._v("#")]),e._v(" Cloud Providers")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/puneet0191/codeceptjs-saucehelper/",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-saucehelper"),t("OutboundLink")],1),e._v(" - a helper which updates "),t("code",[e._v("Test Names")]),e._v(" & "),t("code",[e._v("Test Results")]),e._v(" on Saucelabs")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/PeterNgTr/codeceptjs-bshelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-bshelper"),t("OutboundLink")],1),e._v(" - a helper which updates "),t("code",[e._v("Test Names")]),e._v(" & "),t("code",[e._v("Test Results")]),e._v(" on Browserstack")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/testingbot/codeceptjs-tbhelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-tbhelper"),t("OutboundLink")],1),e._v(" - a helper which updates "),t("code",[e._v("Test Names")]),e._v(" & "),t("code",[e._v("Test Results")]),e._v(" on TestingBot")])]),e._v(" "),t("h2",{attrs:{id:"integrations"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#integrations"}},[e._v("#")]),e._v(" Integrations")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/PeterNgTr/codeceptjs-testrail",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-testrail"),t("OutboundLink")],1),e._v(" - a plugin to integrate with "),t("a",{attrs:{href:"https://www.gurock.com/testrail",target:"_blank",rel:"noopener noreferrer"}},[e._v("Testrail"),t("OutboundLink")],1)])]),e._v(" "),t("h2",{attrs:{id:"visual-testing"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#visual-testing"}},[e._v("#")]),e._v(" Visual-Testing")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/puneet0191/codeceptjs-resemblehelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-resemblehelper"),t("OutboundLink")],1),e._v(" - a helper which helps with visual testing using resemble.js.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.npmjs.com/package/codeceptjs-applitoolshelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-applitoolshelper"),t("OutboundLink")],1),e._v(" - a helper which helps interaction with "),t("a",{attrs:{href:"https://applitools.com",target:"_blank",rel:"noopener noreferrer"}},[e._v("Applitools"),t("OutboundLink")],1)])]),e._v(" "),t("h2",{attrs:{id:"reporters"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#reporters"}},[e._v("#")]),e._v(" Reporters")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/reportportal/agent-js-codecept",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-rphelper"),t("OutboundLink")],1),e._v(" is a CodeceptJS helper which can publish tests results on ReportPortal after execution.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.npmjs.com/package/codeceptjs-xray-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-xray-helper"),t("OutboundLink")],1),e._v(" is a CodeceptJS helper which can publish tests results on "),t("a",{attrs:{href:"https://confluence.xpand-it.com/display/XRAYCLOUD/Import+Execution+Results+-+REST",target:"_blank",rel:"noopener noreferrer"}},[e._v("XRAY"),t("OutboundLink")],1),e._v(".")])]),e._v(" "),t("h2",{attrs:{id:"page-object-code-generator"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#page-object-code-generator"}},[e._v("#")]),e._v(" Page Object Code Generator")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/senthillkumar/CodeCeptJS-PageObject",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-CodeGenerator"),t("OutboundLink")],1),e._v(" is a CodeceptJS custom wrapper which can create page class with action methods from the page object file(JSON) and project setup(Folder Structure).")])]),e._v(" "),t("h2",{attrs:{id:"browser-request-control"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#browser-request-control"}},[e._v("#")]),e._v(" Browser request control")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/luarmr/codeceptjs-resources-check",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-resources-check"),t("OutboundLink")],1),e._v(" Load a URL with Puppeteer and listen to the requests while the page is loading. Enabling count the number or check the sizes of the requests.")])]),e._v(" "),t("h2",{attrs:{id:"assertion-validations"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#assertion-validations"}},[e._v("#")]),e._v(" Assertion & Validations")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://www.npmjs.com/package/codeceptjs-chai",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-chai"),t("OutboundLink")],1),e._v(" is a CodeceptJS helper which wraps\n"),t("a",{attrs:{href:"https://www.chaijs.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("chai"),t("OutboundLink")],1),e._v(" library to complete chai assertion steps with CodeceptJS logging.")])]),e._v(" "),t("h2",{attrs:{id:"other"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#other"}},[e._v("#")]),e._v(" Other")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/thiagodp/codeceptjs-cmdhelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-cmdhelper"),t("OutboundLink")],1),e._v(" allows you to run commands in the terminal/console")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.npmjs.com/package/eslint-plugin-codeceptjs",target:"_blank",rel:"noopener noreferrer"}},[e._v("eslint-plugin-codeceptjs"),t("OutboundLink")],1),e._v(" Eslint rules for CodeceptJS.")])])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/105.ebe71b5e.js b/assets/js/105.ebe71b5e.js new file mode 100644 index 00000000..99060b1e --- /dev/null +++ b/assets/js/105.ebe71b5e.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[105],{404:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("p",[t._v("How to convert "),s("code",[t._v("playwright")]),t._v(" coverage format to "),s("code",[t._v("istanbul")]),t._v(" coverage")]),t._v(" "),s("p",[t._v("To convert coverage generated from "),s("code",[t._v("playwright")]),t._v(" to "),s("code",[t._v("istanbul")]),t._v(" coverage, you first need to install")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://www.npmjs.com/package/v8-to-istanbul",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("v8-to-istanbul")]),s("OutboundLink")],1)])]),t._v(" "),s("p",[t._v("Once installed, convert the coverage to a format which "),s("code",[t._v("istanbul")]),t._v(" can recognize, by writing a script as shown below.")]),t._v(" "),s("div",{staticClass:"language-ts extra-class"},[s("pre",{pre:!0,attrs:{class:"language-ts"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" glob "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'glob'")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" v8toIstanbul "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'v8-to-istanbul'")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" coverage\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("import")]),t._v(" fs "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("from")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'fs'")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" coverageFolder "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("process"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cwd")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("/coverage")]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isExists")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("try")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" fs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("access")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("path"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("catch")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nglob"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("process"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cwd")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/output/coverage/**/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("forEach")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" directory "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" fs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("opendirSync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("item"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" file\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("while")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("file "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" directory"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("readSync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("file "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&&")]),t._v(" file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("includes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.coverage.json'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" fileName "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("fileName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n coverage "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("process"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cwd")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("/output/coverage/")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("fileName"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n directory"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("closeSync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("void")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" entry "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("of")]),t._v(" coverage"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Used to get file name")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" file "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" entry"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("url"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("match")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token regex"}},[s("span",{pre:!0,attrs:{class:"token regex-delimiter"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token regex-source language-regex"}},[t._v("(?:http(s)*:\\/\\/.*\\/)(?.*)")]),s("span",{pre:!0,attrs:{class:"token regex-delimiter"}},[t._v("/")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" converter "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("v8toIstanbul")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("groups"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n source"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" entry"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("source"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" converter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("load")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n converter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("applyCoverage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("entry"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("functions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Store converted coverage file which can later be used to generate report")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" exist "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isExists")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("coverageFolder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("exist"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n fs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mkdirSync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("coverageFolder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("recursive"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" fs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("writeFileSync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("coverageFolder"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("/final.json")]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("JSON")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("stringify")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("converter"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toIstanbul")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("Or simply use the plugin "),s("a",{attrs:{href:"https://github.com/cenfun/codeceptjs-monocart-coverage",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("codeceptjs-monocart-coverage")]),s("OutboundLink")],1)]),t._v(" "),s("ul",[s("li",[t._v("Install")])]),t._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("npm")]),t._v(" i codeceptjs-monocart-coverage\n")])])]),s("ul",[s("li",[t._v("Usage")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// codecept.conf.js")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("plugins")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("monocart")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'codeceptjs-monocart-coverage'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("enabled")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("coverageOptions")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// more options: https://github.com/cenfun/monocart-coverage-reports")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'My CodeceptJS Coverage Report'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("outputDir")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'coverage-reports'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Coverage is only supported in Playwright or Puppeteer")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Playwright")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'chromium'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'http://localhost'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("show")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Puppeteer: {")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// url: 'http://localhost',")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// show: false")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// }")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/106.29abee74.js b/assets/js/106.29abee74.js new file mode 100644 index 00000000..820e9795 --- /dev/null +++ b/assets/js/106.29abee74.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[106],{408:function(e,t,r){"use strict";r.r(t);var a=r(14),s=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h2",{attrs:{id:"todomvc-examples"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#todomvc-examples"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/codecept-js/examples",target:"_blank",rel:"noopener noreferrer"}},[e._v("TodoMVC Examples"),t("OutboundLink")],1)]),e._v(" "),t("p",[t("img",{attrs:{src:"https://github.com/codecept-js/examples/raw/master/todo.png",alt:""}})]),e._v(" "),t("p",[e._v("Playground repository where you can run tests in different helpers on a basic single-page website.")]),e._v(" "),t("p",[e._v("Tests repository demonstrate usage of")]),e._v(" "),t("ul",[t("li",[e._v("Playwright helper")]),e._v(" "),t("li",[e._v("Puppeteer helper")]),e._v(" "),t("li",[e._v("WebDriver helper")]),e._v(" "),t("li",[e._v("TestCafe plugin")]),e._v(" "),t("li",[e._v("Toggle headless mode with env variables")]),e._v(" "),t("li",[e._v("PageObjects")]),e._v(" "),t("li",[e._v("Cucumber syntax")])]),e._v(" "),t("h2",{attrs:{id:"basic-examples"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#basic-examples"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/Codeception/CodeceptJS/tree/master/examples",target:"_blank",rel:"noopener noreferrer"}},[e._v("Basic Examples"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("CodeceptJS repo contains basic tests (both failing and passing) just to show how it works.\nOur team uses it to test new features and run simple scenarios.")]),e._v(" "),t("h2",{attrs:{id:"codeceptjs-cucumber-e2e-framework"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#codeceptjs-cucumber-e2e-framework"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/gkushang/codeceptjs-e2e",target:"_blank",rel:"noopener noreferrer"}},[e._v("CodeceptJS Cucumber E2E Framework"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This repository contains complete E2E framework for CodeceptJS with Cucumber and SauceLabs Integration")]),e._v(" "),t("ul",[t("li",[e._v("CodecepJS-Cucumber E2E Framework")]),e._v(" "),t("li",[e._v("Saucelabs Integration")]),e._v(" "),t("li",[e._v("Run Cross Browser tests in Parallel on SauceLabs with a simple command")]),e._v(" "),t("li",[e._v("Run tests on "),t("code",[e._v("chrome:headless")])]),e._v(" "),t("li",[e._v("Page Objects")]),e._v(" "),t("li",[t("code",[e._v("Should.js")]),e._v(" Assertion Library")]),e._v(" "),t("li",[e._v("Uses "),t("code",[e._v("wdio")]),e._v(" service (selenium-standalone, sauce)")]),e._v(" "),t("li",[e._v("Allure HTML Reports")]),e._v(" "),t("li",[e._v("Uses shared Master configuration")]),e._v(" "),t("li",[e._v("Sample example and feature files of GitHub Features")])]),e._v(" "),t("h2",{attrs:{id:"enterprise-grade-tests"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#enterprise-grade-tests"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/uc-cdis/gen3-qa",target:"_blank",rel:"noopener noreferrer"}},[e._v("Enterprise Grade Tests"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("Complex testing solution by "),t("a",{attrs:{href:"https://github.com/uc-cdis/gen3-qa",target:"_blank",rel:"noopener noreferrer"}},[e._v("Gen3"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("Includes")]),e._v(" "),t("ul",[t("li",[e._v("classical CodeceptJS tests")]),e._v(" "),t("li",[e._v("BDD tests")]),e._v(" "),t("li",[e._v("Jenkins integration")]),e._v(" "),t("li",[e._v("Complex Before/BeforeSuite scripts and more")])]),e._v(" "),t("h2",{attrs:{id:"testing-single-page-application"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#testing-single-page-application"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/bugiratracker/codeceptjs-demo",target:"_blank",rel:"noopener noreferrer"}},[e._v("Testing Single Page Application"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("End 2 end tests for Task management app (currently offline).")]),e._v(" "),t("p",[e._v("Tests repository demonstrate usage of")]),e._v(" "),t("ul",[t("li",[e._v("Puppeteer helper")]),e._v(" "),t("li",[e._v("ApiDataFactory helper")]),e._v(" "),t("li",[e._v("autoLogin plugin")]),e._v(" "),t("li",[e._v("Dynamic config with profiles")])]),e._v(" "),t("h2",{attrs:{id:"practical-e2e-tests"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#practical-e2e-tests"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://gitlab.com/paulvincent/codeceptjs-e2e-testing",target:"_blank",rel:"noopener noreferrer"}},[e._v("Practical E2E Tests"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("Examples from the book "),t("a",{attrs:{href:"https://leanpub.com/codeceptjs/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Practical End 2 End Testing with CodeceptJS"),t("OutboundLink")],1),e._v(" by "),t("strong",[e._v("Paul Vincent Beigang")]),e._v(".")]),e._v(" "),t("p",[e._v("This repository demonstrates usage of:")]),e._v(" "),t("ul",[t("li",[e._v("dynamic config with profiles")]),e._v(" "),t("li",[e._v("testing WYSIWYG editor")]),e._v(" "),t("li",[e._v("GitLab CI")])]),e._v(" "),t("h2",{attrs:{id:"amazon-tests-v2"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#amazon-tests-v2"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://gitlab.com/thanhnguyendh/codeceptjs-wdio-services",target:"_blank",rel:"noopener noreferrer"}},[e._v("Amazon Tests v2"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("Testing Amazon website using Selenium WebDriver.")]),e._v(" "),t("p",[e._v("This repository demonstrates usage of:")]),e._v(" "),t("ul",[t("li",[e._v("WebDriver helper")]),e._v(" "),t("li",[e._v("Page Objects")]),e._v(" "),t("li",[e._v("wdio services (selenium-standalone)")]),e._v(" "),t("li",[e._v("Parallel execution")]),e._v(" "),t("li",[e._v("GitLab CI setup")])]),e._v(" "),t("h2",{attrs:{id:"tests-with-docker-compose"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#tests-with-docker-compose"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/mathesouza/codeceptjs-docker-compose",target:"_blank",rel:"noopener noreferrer"}},[e._v("Tests with Docker Compose"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("Running CodeceptJS tests with Docker Compose")]),e._v(" "),t("p",[e._v("This repository demonstrates usage of:")]),e._v(" "),t("ul",[t("li",[e._v("CodeceptJS Docker image")]),e._v(" "),t("li",[e._v("WebDriver helper")]),e._v(" "),t("li",[e._v("Allure plugin")])]),e._v(" "),t("h2",{attrs:{id:"angularjs-example-tests"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#angularjs-example-tests"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/armno/angular-e2e-codeceptjs-example",target:"_blank",rel:"noopener noreferrer"}},[e._v("AngularJS Example Tests"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("Based on "),t("a",{attrs:{href:"https://medium.com/@armno/setting-up-end-to-end-testing-in-angular-project-with-codeceptjs-ac1784de3420",target:"_blank",rel:"noopener noreferrer"}},[e._v("Setting up End-to-End Testing in Angular Project with CodeceptJS"),t("OutboundLink")],1),e._v(" post by Armno Prommarak.")]),e._v(" "),t("p",[e._v("This repository demonstrates usage of")]),e._v(" "),t("ul",[t("li",[e._v("Puppeteer helper")]),e._v(" "),t("li",[e._v("Working with Angular CLI")]),e._v(" "),t("li",[e._v("Reports with Mochawesome helper")])]),e._v(" "),t("h2",{attrs:{id:"rest-example-tests"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rest-example-tests"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/PeterNgTr/codeceptjs-rest-demo",target:"_blank",rel:"noopener noreferrer"}},[e._v("REST Example Tests"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This repository demonstrates usage of")]),e._v(" "),t("ul",[t("li",[e._v("REST helper")])]),e._v(" "),t("h2",{attrs:{id:"automation-starter"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#automation-starter"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/sjorrillo/automation-starter",target:"_blank",rel:"noopener noreferrer"}},[e._v("Automation Starter"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("The purpose of this application is for learning the basics and how to use good practices and useful tools in automation.")]),e._v(" "),t("ul",[t("li",[e._v("Puppeteer helper")]),e._v(" "),t("li",[e._v("Working with gherkin, also it has type definitions and to be able to use them inside when, given and then make sure you add "),t("code",[e._v("declare function inject(): { I: CodeceptJS.I, [key: string]: any; };")]),e._v("in the "),t("code",[e._v("steps.d.ts")]),e._v("file")]),e._v(" "),t("li",[e._v("Linting "),t("code",[e._v("airbnb-base")]),e._v(", "),t("code",[e._v("codeceptjs/codeceptjs")]),e._v(" and full ES6 support")])]),e._v(" "),t("h2",{attrs:{id:"example-for-using-puppeteer-gherkin-allure-with-parallel-execution"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#example-for-using-puppeteer-gherkin-allure-with-parallel-execution"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/SchnuckySchuster/codeceptJSExample",target:"_blank",rel:"noopener noreferrer"}},[e._v("Example for using: Puppeteer, Gherkin, Allure with parallel execution"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This is a ready to use example that shows how to integrate CodeceptJS with Puppeteer and Allure as reporting tool.")]),e._v(" "),t("ul",[t("li",[e._v("detailed ReadMe")]),e._v(" "),t("li",[e._v("tests written in cucumber alongside tests written in the codeceptJS DSL")]),e._v(" "),t("li",[e._v("puppeteer helper example")]),e._v(" "),t("li",[e._v("test steps, pages, fragments")]),e._v(" "),t("li",[e._v("examples for sequential and parallel execution")]),e._v(" "),t("li",[e._v("generation of allure test results")])]),e._v(" "),t("h2",{attrs:{id:"example-for-advanced-rest-api-testing-typescript-axios-codeceptjs-jest-expect-docker-allure-mock-server-prettier-eslint-pre-commit-jest-unit-tests"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#example-for-advanced-rest-api-testing-typescript-axios-codeceptjs-jest-expect-docker-allure-mock-server-prettier-eslint-pre-commit-jest-unit-tests"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/EgorBodnar/rest-axios-codeceptjs-allure-docker-test-example",target:"_blank",rel:"noopener noreferrer"}},[e._v("Example for Advanced REST API testing: TypeScript, Axios, CodeceptJS, Jest Expect, Docker, Allure, Mock-Server, Prettier + Eslint, pre-commit, Jest Unit Tests "),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("One button example with built-in mocked backend.")]),e._v(" "),t("p",[e._v("If you already have a UI testing solution based on the CodeceptJS and you need to implement advanced REST API testing you can just extend your existing framework. Use this implementation as an example.\nThis is necessary if all integrations with TMS and CI/CD are already configured, and you do not want to reconnect and configure the plugins and libraries used for the new test runner. Use CodeceptJS!")]),e._v(" "),t("ul",[t("li",[e._v("Easy run")]),e._v(" "),t("li",[e._v("Detailed README")]),e._v(" "),t("li",[e._v("Well documented mocked backend's REST API endpoints")]),e._v(" "),t("li",[e._v("HTTP request client with session support and unit tests")]),e._v(" "),t("li",[e._v("Exemplary code control")]),e._v(" "),t("li",[e._v("Ready to launch in a CI/CD system as is")]),e._v(" "),t("li",[e._v("OOP, Test data models and builders, endpoint decorators")])]),e._v(" "),t("h2",{attrs:{id:"playwright-fun-with-codeceptjs"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#playwright-fun-with-codeceptjs"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/PeterNgTr/codeceptjs-playwright-fun",target:"_blank",rel:"noopener noreferrer"}},[e._v("Playwright fun with CodeceptJS"),t("OutboundLink")],1)]),e._v(" "),t("ul",[t("li",[e._v("Tests are written in TS")]),e._v(" "),t("li",[e._v("CI/CD with Github Actions")]),e._v(" "),t("li",[e._v("Page Object Model is applied")]),e._v(" "),t("li",[e._v("ReportPortal Integration")])])])}),[],!1,null,null,null);t.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/107.77c762a0.js b/assets/js/107.77c762a0.js new file mode 100644 index 00000000..4d8ec899 --- /dev/null +++ b/assets/js/107.77c762a0.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[107],{405:function(e,t,o){"use strict";o.r(t);var r=o(14),a=Object(r.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h3",{attrs:{id:"about"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#about"}},[e._v("#")]),e._v(" About")]),e._v(" "),t("p",[e._v("GSoC is an international annual program in which Google awards stipends to university students who successfully complete a requested coding project during the summer.")]),e._v(" "),t("p",[e._v("Codecept-JS has decided to apply to participate in GSoC 2020, Please note that the final list of GSoC 2020 organizations will be announced on 22nd Feb 2020.")]),e._v(" "),t("p",[e._v("To read more about the program please visit "),t("a",{attrs:{href:"https://summerofcode.withgoogle.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("GSoC Program"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("The timeline for the program can be found on "),t("a",{attrs:{href:"https://summerofcode.withgoogle.com/how-it-works/#timeline",target:"_blank",rel:"noopener noreferrer"}},[e._v("Official Program Timeline"),t("OutboundLink")],1)]),e._v(" "),t("h3",{attrs:{id:"contact-information"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#contact-information"}},[e._v("#")]),e._v(" Contact Information")]),e._v(" "),t("p",[e._v("For all the students who are interested in working with Codecept-JS organization for GSoC 2020, you can start by reaching out to our organization team by posting your interest in our "),t("a",{attrs:{href:"https://codecept.discourse.group/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Forum"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("Read about the Project on our "),t("a",{attrs:{href:"https://codecept.io/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Official Project Website"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("You can also join our Community Slack, which is used for community conversation, our GSoC team will be available on slack, we will have dedicated channel for GSoC Students and Projects, join "),t("a",{attrs:{href:"http://bit.ly/chat-codeceptjs",target:"_blank",rel:"noopener noreferrer"}},[e._v("here"),t("OutboundLink")],1)]),e._v(" "),t("h3",{attrs:{id:"student-information"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#student-information"}},[e._v("#")]),e._v(" Student Information")]),e._v(" "),t("p",[e._v("If you are a student and are interested in participating, the following is useful information.")]),e._v(" "),t("h4",{attrs:{id:"proposal-guidelines"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#proposal-guidelines"}},[e._v("#")]),e._v(" Proposal Guidelines")]),e._v(" "),t("p",[e._v("Before applying as a Codeceptjs Contributor, we suggest you review the points below. It can help you with creating a strong Proposal.")]),e._v(" "),t("ol",[t("li",[e._v("Read about Codeceptjs on our "),t("a",{attrs:{href:"https://codecept.io/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Official Website"),t("OutboundLink")],1)]),e._v(" "),t("li",[e._v("Setup Codeceptjs on your working system, and then Go through the list of open issues on our "),t("a",{attrs:{href:"https://github.com/Codeception/CodeceptJS/issues",target:"_blank",rel:"noopener noreferrer"}},[e._v("Github Repo"),t("OutboundLink")],1),e._v(", try to help us with fixing some of them, or help in testing existing PR's from our developers.")]),e._v(" "),t("li",[e._v("Go through the guides available on our official website, understand how our helpers work and check the list of current helpers on our organization "),t("a",{attrs:{href:"https://github.com/codecept-js",target:"_blank",rel:"noopener noreferrer"}},[e._v("Github"),t("OutboundLink")],1)])]),e._v(" "),t("h4",{attrs:{id:"application-template"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#application-template"}},[e._v("#")]),e._v(" Application Template")]),e._v(" "),t("p",[e._v("If you are planning to send us a proposal, please make sure you have addressed the following elements:")]),e._v(" "),t("ol",[t("li",[e._v("About you (your background, experience, education, hobbies)")]),e._v(" "),t("li",[e._v("Project background (current state of what exist)")]),e._v(" "),t("li",[e._v("Design/description of work")]),e._v(" "),t("li",[e._v("Benefit of your work to the project users and developers")]),e._v(" "),t("li",[e._v("Deliverables")]),e._v(" "),t("li",[e._v("Scheduling")]),e._v(" "),t("li",[e._v("Other commitments (i.e., exams, part time work, holidays, lectures, etc.)")]),e._v(" "),t("li",[e._v("Community engagement (involvement, sample PR's, forum discussions, other open-source involvement)")])]),e._v(" "),t("h3",{attrs:{id:"idea-s-for-gsoc-2020"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#idea-s-for-gsoc-2020"}},[e._v("#")]),e._v(" Idea's for GSoC 2020")]),e._v(" "),t("h4",{attrs:{id:"improve-visual-testing-support-in-codeceptjs"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#improve-visual-testing-support-in-codeceptjs"}},[e._v("#")]),e._v(" Improve Visual Testing Support in Codeceptjs")]),e._v(" "),t("p",[e._v("CodeceptJS has a visual testing helper which is based on resemble.js, instructions to set up and use the helper can be found "),t("a",{attrs:{href:"https://github.com/codecept-js/codeceptjs-resemblehelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("here"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("We have several improvements we want to make to our helper, here is the list.")]),e._v(" "),t("ol",[t("li",[e._v("Add Support for Allure Reporter")]),e._v(" "),t("li",[e._v("Add Support for Visual Testing with "),t("a",{attrs:{href:"https://codecept.io/ui/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Codecept UI"),t("OutboundLink")],1)]),e._v(" "),t("li",[e._v("Support for "),t("a",{attrs:{href:"https://codecept.io/parallel/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Workers"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("Knowledge Prerequisite: Github, Nodejs, CodeceptJS, Resemble.js")]),e._v(" "),t("p",[e._v("Difficulty: Medium")]),e._v(" "),t("p",[e._v("Possible Mentors: Puneet Kala, Koushik Mohan")]),e._v(" "),t("h4",{attrs:{id:"improve-codecept-ui"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#improve-codecept-ui"}},[e._v("#")]),e._v(" Improve Codecept UI")]),e._v(" "),t("p",[e._v("CodeceptJS has an interactive, graphical test runner, which is called CodeceptUI. It works on Browsers and helps in managing tests.\nWe need help with improving the CodeceptUI project, fixing existing issues.")]),e._v(" "),t("ol",[t("li",[e._v("To get started, please read about CodeceptUI "),t("a",{attrs:{href:"https://codecept.io/ui/",target:"_blank",rel:"noopener noreferrer"}},[e._v("here"),t("OutboundLink")],1)]),e._v(" "),t("li",[e._v("To get your hands on the code, you can check out the Repo "),t("a",{attrs:{href:"https://github.com/codecept-js/ui",target:"_blank",rel:"noopener noreferrer"}},[e._v("here"),t("OutboundLink")],1),e._v(", look at the list of open issues and start with fixing them.")])]),e._v(" "),t("p",[e._v("Knowledge Prerequisite: Github, CodeceptJS, JS, VueJS, Express.js, WebSockets, NodeJS")]),e._v(" "),t("p",[e._v("Difficulty: Medium")]),e._v(" "),t("p",[e._v("Possible Mentors: Michael Bodnarchuk, Paul")])])}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/108.145fab30.js b/assets/js/108.145fab30.js new file mode 100644 index 00000000..19a82cc7 --- /dev/null +++ b/assets/js/108.145fab30.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[108],{409:function(e,t,o){"use strict";o.r(t);var r=o(14),n=Object(r.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("Wiki Pages contain community content which is partly copied into the website.")]),e._v(" "),t("ul",[t("li",[e._v(":toolbox: "),t("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/wiki/Community-Helpers-&-Plugins",target:"_blank",rel:"noopener noreferrer"}},[e._v("Community Helpers & Plugins"),t("OutboundLink")],1),e._v(" - collection of community-driven plugins and helpers (synced with website).")]),e._v(" "),t("li",[e._v("👀 "),t("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/wiki/Examples",target:"_blank",rel:"noopener noreferrer"}},[e._v("Examples"),t("OutboundLink")],1),e._v(" - collection of CodeceptJS sample projects (synced with website).")]),e._v(" "),t("li",[e._v("📖 "),t("a",{attrs:{href:"https://github.com/Codeception/CodeceptJS/wiki/Books-&-Posts",target:"_blank",rel:"noopener noreferrer"}},[e._v("Books & Posts"),t("OutboundLink")],1),e._v(" - posts about CodeceptJS (synced with website).")]),e._v(" "),t("li",[e._v("📺 "),t("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/wiki/Videos",target:"_blank",rel:"noopener noreferrer"}},[e._v("Videos"),t("OutboundLink")],1),e._v(" - videos on CodeceptJS (synced with website).\nAdd your own entries to these lists.")])]),e._v(" "),t("p",[e._v("Other useful links:")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"http://codecept.io",target:"_blank",rel:"noopener noreferrer"}},[e._v("Official Site"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/Codeception/CodeceptJS/wiki/Roadmap",target:"_blank",rel:"noopener noreferrer"}},[e._v("Roadmap"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/Codeception/CodeceptJS",target:"_blank",rel:"noopener noreferrer"}},[e._v("Code on Github"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/Codeception/CodeceptJS/blob/master/CHANGELOG.md",target:"_blank",rel:"noopener noreferrer"}},[e._v("Change log"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/Codeception/CodeceptJS/wiki/Google-Summer-of-Code-(GSoC)-2020",target:"_blank",rel:"noopener noreferrer"}},[e._v("GSoC"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/109.846cc03f.js b/assets/js/109.846cc03f.js new file mode 100644 index 00000000..9e398df8 --- /dev/null +++ b/assets/js/109.846cc03f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[109],{410:function(e,a,t){"use strict";t.r(a);var i=t(14),s=Object(i.a)({},(function(){var e=this,a=e._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[a("h1",{attrs:{id:"migrating-from-appium-1-x-to-appium-2-x"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#migrating-from-appium-1-x-to-appium-2-x"}},[e._v("#")]),e._v(" Migrating from Appium 1.x to Appium 2.x")]),e._v(" "),a("p",[e._v("This document is a guide for those who are using Appium 1.x and wish to migrate to Appium 2.x. It contains a list of breaking changes and how to migrate your environments or test suites to ensure compatibility with Appium 2.0.")]),e._v(" "),a("h1",{attrs:{id:"overview-of-appium-2-0"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#overview-of-appium-2-0"}},[e._v("#")]),e._v(" Overview of Appium 2.0")]),e._v(" "),a("p",[e._v('Appium 2.0 is the most major new release of Appium in over 5 years. The changes in Appium 2.0 are not primarily related to changes in automation behaviors for specific platforms. Instead, Appium 2.0 reenvisions Appium as a platform where "drivers" (code projects that introduce support for automation of a given platform) and "plugins" (code projects that allow for overriding, altering, extending, or adding behaviors to Appium) can be easily created and shared.')]),e._v(" "),a("p",[e._v("At the same time, the Appium project is taking the opportunity to remove many old and deprecated bits of functionality.")]),e._v(" "),a("p",[e._v("Together these do introduce a few breaking changes to how Appium is installed, how drivers and various features are managed, and protocol support. These are detailed below.")]),e._v(" "),a("h1",{attrs:{id:"breaking-changes"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#breaking-changes"}},[e._v("#")]),e._v(" Breaking Changes")]),e._v(" "),a("p",[e._v("Here we call out the breaking changes and what you need to do to account for them.")]),e._v(" "),a("h2",{attrs:{id:"default-server-base-path"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#default-server-base-path"}},[e._v("#")]),e._v(" ‼ Default server base path")]),e._v(" "),a("p",[e._v("With Appium 1.x, the server would accept commands by default on http://localhost:4723/wd/hub. The /wd/hub base path was a legacy convention from the days of migrating from Selenium 1 to Selenium 2, and is no longer relevant. As such the default base path for the server is now /. If you want to retain the old behaviour, you can set the base path via a command line argument as follows:")]),e._v(" "),a("p",[a("code",[e._v("appium --base-path=/wd/hub")])]),e._v(" "),a("h2",{attrs:{id:"installing-drivers-during-setup"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#installing-drivers-during-setup"}},[e._v("#")]),e._v(" ‼ Installing drivers during setup")]),e._v(" "),a("p",[e._v("When you installed Appium 1.x, all available drivers would be installed at the same time as the main Appium server. This is no longer the case. Simply installing Appium 2.0 (e.g., by npm install -g appium@next), will install the Appium server only, but no drivers. To install drivers, you must instead use the new "),a("a",{attrs:{href:"https://appium.github.io/appium/docs/en/2.0/cli/extensions/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Appium extension CLI"),a("OutboundLink")],1),e._v(". For example, to install the latest versions of the XCUITest and UiAutomator2 drivers, after installing Appium you would run the following commands:")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("appium driver install uiautomator2,xcuitest # installs the latest driver version \n")])])]),a("p",[e._v("At this point, your drivers are installed and ready. There's a lot more you can do with this CLI so be sure to check out the docs on it. If you're running in a CI environment or want to install Appium along with some drivers all in one step, you can do so using some special flags during install, for example:")]),e._v(" "),a("p",[a("code",[e._v("npm install --global appium --drivers=xcuitest,uiautomator2")]),e._v("\nThis will install Appium and the two drivers for you in one go. Please uninstall any existing Appium 1.x npm packages (with npm uninstall -g appium) if you get an installation or startup error.")]),e._v(" "),a("h2",{attrs:{id:"capabilities"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#capabilities"}},[e._v("#")]),e._v(" ‼ Capabilities")]),e._v(" "),a("p",[e._v('One significant difference between old and new protocols is in the format of capabilities. Previously called "desired capabilities", and now called simply "capabilities", there is now a requirement for a so-called "vendor prefix" on any non-standard capabilities. The list of standard capabilities is given in the '),a("a",{attrs:{href:"https://www.w3.org/TR/webdriver/#capabilities",target:"_blank",rel:"noopener noreferrer"}},[e._v("WebDriver Protocol spec"),a("OutboundLink")],1),e._v(", and includes a few commonly used capabilities such as browserName and platformName.")]),e._v(" "),a("p",[e._v('These standard capabilities continue to be used as-is. All other capabilities must include a "vendor prefix" in their name. A vendor prefix is a string followed by a colon, such as appium:. Most of Appium\'s capabilities go beyond the standard W3C capabilities and must therefore include vendor prefixes (we recommend that you use appium: unless directed otherwise by documentation). For example:')]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("`appium:app`\n`appium:noReset`\n`appium:deviceName`\n")])])]),a("p",[e._v("This requirement may or may not be a breaking change for your test suites when targeting Appium 2.0. If you're using an updated Appium client (at least one maintained by the Appium team), the client will add the appium: prefix for you on all necessary capabilities automatically. New versions of "),a("a",{attrs:{href:"https://github.com/appium/appium-inspector",target:"_blank",rel:"noopener noreferrer"}},[e._v("Appium Inspector"),a("OutboundLink")],1),e._v(" will also do this. Cloud-based Appium providers may also do this. So simply be aware that if you get any messages to the effect that your capabilities lack a vendor prefix, this is how you solve that problem.")]),e._v(" "),a("p",[e._v("To make everyone's lives a bit easier with CodeceptJS, you don't need to update your capabilities to include \"vendor prefix\", CodeceptJS does it for you out of the box.")]),e._v(" "),a("h2",{attrs:{id:"webdriverio-upgrade"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#webdriverio-upgrade"}},[e._v("#")]),e._v(" ‼ WebdriverIO upgrade")]),e._v(" "),a("p",[e._v("CodeceptJS should be installed with webdriverio support, as the moment of testing, "),a("code",[e._v("webdriverio@8.6.3")]),e._v(" works seamlessly:")]),e._v(" "),a("div",{staticClass:"language-bash extra-class"},[a("pre",{pre:!0,attrs:{class:"language-bash"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[e._v("npm")]),e._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[e._v("install")]),e._v(" codeceptjs webdriverio@8.6.3 "),a("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--save")]),e._v("\n")])])]),a("h2",{attrs:{id:"codeceptjs-configuration"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#codeceptjs-configuration"}},[e._v("#")]),e._v(" ‼ CodeceptJS configuration")]),e._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[e._v("...\n appiumV2: true, // set this to true to try out appium 2.x\n 'app': `${process.cwd()}/build/Monefy_Pro_v1.15.0.apk`,\n 'platform': 'android',\n 'device': 'emulator',\n 'port': DEFAULT_PORT,\n 'path': '/wd/hub',\n browser: '',\n desiredCapabilities: {\n 'appPackage': data.packageName,\n 'deviceName': process.env.DEVICE || 'Emulator',\n 'platformName': process.env.PLATFORM || 'android',\n 'platformVersion': process.env.OS_VERSION || '11.0',\n 'automationName': process.env.ENGINE || 'UIAutomator2',\n 'avd': process.env.UDID || 'Pixel_XL_API_30',\n 'newCommandTimeout': 300000,\n 'androidDeviceReadyTimeout': 300000,\n 'androidInstallTimeout': 90000,\n 'appWaitDuration': 300000,\n 'autoGrantPermissions': true,\n 'gpsEnabled': true,\n 'isHeadless': false,\n 'noReset': false,\n 'noSign': true,\n }\n...\n")])])]),a("p",[e._v("Demo project to try with Appium v2: https://github.com/kobenguyent/thanh-nguyen/tree/main/task2")])])}),[],!1,null,null,null);a.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/110.dd09c149.js b/assets/js/110.dd09c149.js new file mode 100644 index 00000000..5cc10907 --- /dev/null +++ b/assets/js/110.dd09c149.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[110],{407:function(e,t,s){"use strict";s.r(t);var a=s(14),o=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[e._v("This is the guide for maintainers:")]),e._v(" "),t("h2",{attrs:{id:"release-process"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#release-process"}},[e._v("#")]),e._v(" Release Process")]),e._v(" "),t("ol",[t("li",[e._v("Pull the latest changes from main branch for release stream e.g. 3.x")]),e._v(" "),t("li",[e._v("Create a release branch and switch to it by "),t("code",[e._v("git checkout -b release-x.x.x")])]),e._v(" "),t("li",[e._v("Update version in "),t("code",[e._v("package.json")])]),e._v(" "),t("li",[e._v("Go through the commits for the new release and add them to the CHANGELOG.md:")])]),e._v(" "),t("ul",[t("li",[e._v("Changelog should be written for humans (not for robots).")]),e._v(" "),t("li",[e._v("Use simple wording explaining what the change is, how to use a new feature (maybe with a code example) and mention the related issue.")]),e._v(" "),t("li",[e._v("When using "),t("code",[e._v("#123")]),e._v(" a link for issue #123 will be automatically added.")]),e._v(" "),t("li",[e._v("A contributor must be mentioned. We use GitHub names with "),t("code",[e._v("@")]),e._v(" prefix. A link to user profile is automatically added.")])]),e._v(" "),t("ol",{attrs:{start:"5"}},[t("li",[e._v("Run "),t("code",[e._v("./runok.js docs")]),e._v(" to build documentation")]),e._v(" "),t("li",[e._v("Commit all changes, push and create a PR")]),e._v(" "),t("li",[e._v("Check that all tests pass and merge your PR")]),e._v(" "),t("li",[e._v("Run "),t("code",[e._v("./runok.js release")]),e._v(" to publish latest release. The website will be updated.")])]),e._v(" "),t("ul",[t("li",[e._v("To update version for patch release: "),t("code",[e._v("./runok.js release patch")])]),e._v(" "),t("li",[e._v("To update version for minor release: "),t("code",[e._v("./runok.js release minor")])])]),e._v(" "),t("ol",{attrs:{start:"9"}},[t("li",[e._v("Post announcements in Twitter & Slack")])]),e._v(" "),t("h2",{attrs:{id:"updating-the-website"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#updating-the-website"}},[e._v("#")]),e._v(" Updating the website")]),e._v(" "),t("ul",[t("li",[e._v("Run "),t("code",[e._v("./runok.js docs:helpers")]),e._v(" to build docs from helpers")]),e._v(" "),t("li",[e._v("Run "),t("code",[e._v("./runok.js publish:site")]),e._v(" to update a website")])])])}),[],!1,null,null,null);t.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/111.95924ac1.js b/assets/js/111.95924ac1.js new file mode 100644 index 00000000..335043e5 --- /dev/null +++ b/assets/js/111.95924ac1.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[111],{412:function(e,t,r){"use strict";r.r(t);var o=r(14),n=Object(o.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("p",[t("a",{attrs:{href:"https://github.com/Codeception/CodeceptJS/projects",target:"_blank",rel:"noopener noreferrer"}},[e._v("Upcoming releases"),t("OutboundLink")],1)]),e._v(" "),t("h2",{attrs:{id:"backlog"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#backlog"}},[e._v("#")]),e._v(" Backlog")]),e._v(" "),t("ul",[t("li",[e._v("Shadow-DOM locator integration with webdriverio 5.x")]),e._v(" "),t("li",[e._v("Cypress integration")]),e._v(" "),t("li",[e._v("Reuse a single browser session while writing tests")])]),e._v(" "),t("hr"),e._v(" "),t("h2",{attrs:{id:"done"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#done"}},[e._v("#")]),e._v(" Done")]),e._v(" "),t("p",[e._v("To make those features implemented, consider "),t("a",{attrs:{href:"https://github.com/Codeception/CodeceptJS/issues/1462",target:"_blank",rel:"noopener noreferrer"}},[e._v("sponsoring CodeceptJS"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("ul",[t("li",[e._v("~GraphQL helper~")]),e._v(" "),t("li",[e._v("~Cypress-like Development mode:~\n"),t("ul",[t("li",[e._v("~UI for selecting and executing tests~")])])]),e._v(" "),t("li",[e._v("~"),t("a",{attrs:{href:"https://github.com/wix/Detox",target:"_blank",rel:"noopener noreferrer"}},[e._v("Detox"),t("OutboundLink")],1),e._v(" integration for React Native and mobile testing~")]),e._v(" "),t("li",[e._v("~TestCafe integration~")]),e._v(" "),t("li",[e._v("~Parallel execution via workers (improves CPU consumation, reporting)~")]),e._v(" "),t("li",[e._v("~Mock Request/Response in Puppeteer helper via "),t("a",{attrs:{href:"https://github.com/Netflix/pollyjs",target:"_blank",rel:"noopener noreferrer"}},[e._v("PollyJS"),t("OutboundLink")],1),e._v(".~")]),e._v(" "),t("li",[e._v("Update BDD/Gherkin support to Gherkin version 6 specification\n"),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/cucumber/cucumber/blob/master/gherkin/CHANGELOG.md#6013---2018-09-25",target:"_blank",rel:"noopener noreferrer"}},[e._v("See Version 6.0.13"),t("OutboundLink")],1)])])])])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/112.31081a01.js b/assets/js/112.31081a01.js new file mode 100644 index 00000000..205b6f37 --- /dev/null +++ b/assets/js/112.31081a01.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[112],{414:function(e,o,t){"use strict";t.r(o);var v=t(14),_=Object(v.a)({},(function(){var e=this,o=e._self._c;return o("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[o("p",[e._v("Created by "),o("a",{attrs:{href:"https://testomat.io/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Testomat.io"),o("OutboundLink")],1)]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/graphql/GraphQL_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/graphql/GraphQL_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("GraphQL")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("basic queries")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should send a query: read")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("basic mutations")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should send a mutation: create")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should send a mutation: delete")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/graphql/GraphQLDataFactory_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/graphql/GraphQLDataFactory_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("GraphQLDataFactory")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("create and cleanup records")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should create a new user")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create a new user with predefined field")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should update request with onRequest")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should cleanup created data")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create multiple users and cleanup after")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not remove records if cleanup:false")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/helper/Appium_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/helper/Appium_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Appium")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("app installation : #seeAppIsInstalled, #installApp, #removeApp, #seeAppIsNotInstalled")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("#grabAllContexts, #grabContext, #grabCurrentActivity, #grabNetworkConnection, #grabOrientation, #grabSettings")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should grab all available contexts for screen")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab current context")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab current activity of app")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab network connection settings")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab orientation")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab custom settings")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should remove App and install it again")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should assert when app is/is not installed")])])])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("see seeCurrentActivity: #seeCurrentActivityIs")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return .HomeScreenActivity for default screen")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should assert for wrong screen")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("device lock : #seeDeviceIsLocked, #seeDeviceIsUnlocked")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return correct status about lock @second")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("device orientation : #seeOrientationIs #setOrientation")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return correct status about lock")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should set device orientation")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("app context and activity: #_switchToContext, #switchToWeb, #switchToNative")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should switch context")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to native and web contexts @quick")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch activity")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#setNetworkConnection, #setSettings")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should set Network Connection (airplane mode on)")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should set custom settings")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#hideDeviceKeyboard")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should hide device Keyboard @quick")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should assert if no keyboard")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#sendDeviceKeyEvent")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should react on pressing keycode")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#openNotifications")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should react on notification opening")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#makeTouchAction")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should react on touch actions")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should react on swipe action")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should react on swipeDown action")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("run simplified swipeDown @quick")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should react on swipeUp action")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should react on swipeRight action")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should react on swipeLeft action")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should react on touchPerform action")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should assert when you dont scroll the document anymore")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should react on swipeTo action")])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#performTouchAction")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should react on swipeUp action @second")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should react on swipeDown action @second")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should react on swipeLeft action")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should react on swipeRight action")])])])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#pullFile")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should pull file to local machine")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("see text : #see")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should work inside elements @second")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should work inside web view as normally @quick")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#appendField")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be able to send special keys to element @second")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeInSource")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check for text to be in HTML source")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForText")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return error if not present")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeNumberOfElements "),o("code",[e._v("@second")])]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return 1 as count")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("see element : #seeElement, #dontSeeElement")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check visible elements on page @quick")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#click "),o("code",[e._v("@quick")])]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should click by accessibility id")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click by xpath")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#fillField, #appendField "),o("code",[e._v("@second")])]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should fill field by accessibility id")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fill field by xpath")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should append field value @second")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#clearField")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should clear a given element")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#grabTextFrom, #grabValueFrom, #grabAttributeFrom")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should grab text from page")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab attribute from element")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#saveScreenshot")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should create a screenshot file in output dir")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#runOnIOS, #runOnAndroid, #runInWeb")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should use Android locators")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should execute only on Android @quick")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should execute only on Android >= 5.0 @quick")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should execute only in Web")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/helper/AppiumWeb_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/helper/AppiumWeb_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Appium Web")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("current url : #seeInCurrentUrl, #seeCurrentUrlEquals, ...")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check for url fragment")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check for equality")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("see text : #see")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check text on site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check text inside element")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("see element : #seeElement, #dontSeeElement")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check visible elements on page")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#click")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should click by text")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click by css")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click by non-optimal css")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click by xpath")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click on context")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click link with inner span")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click buttons as links")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#grabTextFrom, #grabValueFrom, #grabAttributeFrom")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should grab text from page")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab value from field")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab attribute from element")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#within")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should work using within operator")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/helper/Nightmare_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/helper/Nightmare_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Nightmare")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("open page : #amOnPage")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should open main page of configured site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open any page of configured site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open absolute url")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open same page twice without error")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForFunction")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for function returns true")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should pass arguments and wait for function returns true")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#moveCursorTo")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should trigger hover event")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("scripts Inject")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should reinject scripts after navigating to new page")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("see text : #see")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should fail when text is not on site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail when clickable element not found")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail when text on site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail when test is not in context")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#locate")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should use locate to check element")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("window size #resizeWindow")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should set initial window size")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should resize window to specific dimensions")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("refresh page")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should refresh the current page")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeNumberOfElements")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return 1 as count")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/helper/Playwright_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/helper/Playwright_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Playwright")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("open page : #amOnPage")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should open main page of configured site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open any page of configured site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open absolute url")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("grabDataFromPerformanceTiming")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return data from performance timing")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForFunction")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for function returns true")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should pass arguments and wait for function returns true")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitToHide")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for hidden element")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for hidden element by XPath")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitNumberOfVisibleElements")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for a specified number of elements on the page")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for a specified number of elements on the page using a css selector")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for a specified number of elements which are not yet attached to the DOM")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#moveCursorTo")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should trigger hover event")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not trigger hover event because of the offset is beyond the element")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#switchToNextTab, #switchToPreviousTab, #openNewTab, #closeCurrentTab, #closeOtherTabs, #grabNumberOfOpenTabs")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should only have 1 tab open when the browser starts and navigates to the first page")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to next tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should assert when there is no ability to switch to next tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should close current tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should close other tabs")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open new tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to previous tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should assert when there is no ability to switch to previous tab")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("popup : #acceptPopup, #seeInPopup, #cancelPopup, #grabPopupText")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should accept popup window")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should accept popup window (using default popup action type)")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should cancel popup")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check text in popup")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab text from popup")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return null if no popup is visible (do not throw an error)")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeNumberOfElements")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return 1 as count")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#switchTo")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should switch reference to iframe content")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return error if iframe selector is invalid")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return error if iframe selector is not iframe")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return to parent frame given a null locator")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeInSource, #grabSource")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check for text to be in HTML source")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab the source")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeTitleEquals")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check that title is equal to provided one")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeTextEquals")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check text is equal to provided one")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#_locateClickable")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should locate a button to click")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not locate a non-existing checkbox using _locateClickable")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#_locateCheckable")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should locate a checkbox")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#_locateFields")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should locate a field")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not locate a non-existing field")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("check fields: #seeInField, #seeCheckboxIsChecked, ...")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should throw error if field is not empty")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check values in checkboxes")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check values with boolean")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check values in radio")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check values in select")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check for empty select field")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check for select multiple field")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#pressKey, #pressKeyDown, #pressKeyUp")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be able to send special keys to element")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should use modifier key based on operating system")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should show correct numpad or punctuation key when Shift modifier is active")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForEnabled")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for input text field to be enabled")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for input text field to be enabled by xpath")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for a button to be enabled")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForValue")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for expected value for given locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for expected value for given css locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for expected value for given xpath locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should only wait for one of the matching elements to contain the value given xpath locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should only wait for one of the matching elements to contain the value given css locator")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#grabHTMLFrom")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should grab inner html from an element using xpath query")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab inner html from an element using id query")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab inner html from multiple elements")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab inner html from within an iframe")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#grabBrowserLogs")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should grab browser logs")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#dragAndDrop")]),e._v(" "),o("ul",[o("li",[o("p",[e._v("✔️ "),o("code",[e._v("Drag item from source to target (no iframe) @dragNdrop")]),e._v(" "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/598394b1b7498738fbcb495617b756ab48ea6af5/test/helper/Playwright_test.js#L580",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("Drag and drop from within an iframe")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/ef5c8da6b66bff845a4a37a1ab0c69f3c46ffb65/test/helper/Playwright_test.js#L580",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("Drag and drop from within an iframe")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/5164f0090748d2eca00c152d82a55338ac1e21ec/test/helper/Playwright_test.js#L580",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("Drag and drop from within an iframe")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/85fe5397629172c36cd70e35bd4c14bb6746a832/test/helper/Playwright_test.js#L580",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("Drag and drop from within an iframe")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/265dcb3a44f2fea26351992728a4f31bc3249290/test/helper/Playwright_test.js#L580",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("Drag and drop from within an iframe")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/22f28d62df741a9dbf0e9b2e35d27d0dcbc98024/test/helper/Playwright_test.js#L580",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("Drag and drop from within an iframe")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/4825f53e0cc308c57bf6e55d9aed7da58bc99161/test/helper/Playwright_test.js#L580",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("Drag and drop from within an iframe")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/12d55f9271591c85f95fa6d017f30b5f9922aa33/test/helper/Playwright_test.js#L580",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("Drag and drop from within an iframe")]),o("OutboundLink")],1),e._v(" ⚠")])]),e._v(" "),o("li",[o("p",[o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/helper/Playwright_test.js#L580",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("Drag and drop from within an iframe")]),o("OutboundLink")],1),e._v(" ⚠️ "),o("em",[e._v("skipped")])])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#switchTo frame")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should switch to frame using name")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to root frame")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to frame using frame number")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#dragSlider")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should drag scrubber to given position")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#uncheckOption")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should uncheck option that is currently checked")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should NOT uncheck option that is NOT currently checked")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#grabElementBoundingRect")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should get the element bounding rectangle")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should get the element width")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should get the element height")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#handleDownloads")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should dowload file")])])])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#_startBrowser")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should throw an exception when endpoint is unreachable")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should manage pages in remote browser")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("Playwright - BasicAuth")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("open page with provided basic auth")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be authenticated")])])])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("Playwright - Emulation")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should open page as iPhone")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/helper/Protractor_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/helper/Protractor_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Protractor")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("open page : #amOnPage")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should open main page of configured site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open absolute url")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("current url : #seeInCurrentUrl, #seeCurrentUrlEquals, ...")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check for url fragment")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check for equality")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("see text : #see")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check text on site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check text inside element")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("see element : #seeElement, #dontSeeElement")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check visible elements on page")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#click")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should click by text")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click by css")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click by non-optimal css")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click by xpath")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click on context")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click link with inner span")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click buttons as links")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#checkOption")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check option by css")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check option by strict locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check option by name")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check option by label")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#selectOption")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should select option by css")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should select option by label")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should select option by label and value")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should select option in grouped select")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#fillField, #appendField")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should fill input by label")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fill textarea by label")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fill field by placeholder")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fill field by css")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fill field by model")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fill field by name")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fill textarea by name")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fill textarea by css")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fill textarea by model")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should append value to field")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("check fields: #seeInField, #seeCheckboxIsChecked, ...")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check for empty field")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should throw error if field is not empty")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check field equals")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check values in select")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check checkbox is checked :)")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#grabTextFrom, #grabValueFrom, #grabAttributeFrom")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should grab text from page")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab value from field")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab value from select")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab attribute from element")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("page title : #seeTitle, #dontSeeTitle, #grabTitle, #seeTitleEquals")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check page title")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab page title")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check that title is equal to provided one")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeTextEquals")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check text is equal to provided one")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#saveScreenshot")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should create a screenshot file in output dir")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create full page a screenshot file in output dir")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#switchToNextTab, #switchToPreviousTab, #openNewTab, #closeCurrentTab, #closeOtherTabs, #grabNumberOfOpenTabs")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should only have 1 tab open when the browser starts and navigates to the first page")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to next tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should assert when there is no ability to switch to next tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should assert when there is no ability to switch to previous tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should close current tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should close other tabs")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open new tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to previous tab")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("cookies : #setCookie, #clearCookies, #seeCookie")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should do all cookie stuff")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeInSource, #grabSource")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check for text to be in HTML source")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab the source")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("window size : #resizeWindow")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should change the active window size")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#amOutsideAngularApp")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should work outside angular app")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch between applications")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("waitForVisible")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("wait for element")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForText")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for text")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for text in context")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return error if not present")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return error if waiting is too small")])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeNumberOfElements")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return 1 as count")])])])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/helper/ProtractorWeb_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/helper/ProtractorWeb_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Protractor-NonAngular")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("window size #resizeWindow")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should set initial window size")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should resize window to specific dimensions")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("open page : #amOnPage")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should open main page of configured site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open any page of configured site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open absolute url")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#pressKey")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be able to send special keys to element")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("see text : #see")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should fail when text is not on site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail when text on site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail when test is not in context")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("SmartWait")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for element to appear")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for clickable element appear")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for clickable context to appear")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for text context to appear")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#switchTo frame")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should switch to frame using name")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to root frame")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to frame using frame number")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForFunction")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for function returns true")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should pass arguments and wait for function returns true")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitNumberOfVisibleElements")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for a specified number of elements on the page")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for a specified number of elements on the page using a css selector")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for a specified number of elements which are not yet attached to the DOM")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForEnabled")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for input text field to be enabled")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for input text field to be enabled by xpath")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for a button to be enabled")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForValue")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for expected value for given locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for expected value for given css locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for expected value for given xpath locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should only wait for one of the matching elements to contain the value given xpath locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should only wait for one of the matching elements to contain the value given css locator")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#grabHTMLFrom")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should grab inner html from an element using xpath query")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab inner html from an element using id query")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab inner html from multiple elements")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("popup : #acceptPopup, #seeInPopup, #cancelPopup")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should accept popup window")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should cancel popup")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check text in popup")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab text from popup")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return null if no popup is visible (do not throw an error)")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#grabBrowserLogs")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should grab browser logs")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab browser logs across pages")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#dragAndDrop")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("Drag item from source to target (no iframe) @dragNdrop")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("Drag and drop from within an iframe")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#_locateClickable")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should locate a button to click")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not locate a non-existing checkbox using _locateClickable")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#_locateCheckable")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should locate a checkbox")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not locate a non-existing checkbox")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#_locateFields")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should locate a field")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not locate a non-existing field")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/helper/Puppeteer_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/helper/Puppeteer_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Puppeteer - BasicAuth")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("open page with provided basic auth")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be authenticated")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should be authenticated on second run")])])])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("Puppeteer")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Session")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should not fail for localStorage.clear() on about:blank")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("open page : #amOnPage")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should open main page of configured site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open any page of configured site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open absolute url")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should be unauthenticated")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("grabDataFromPerformanceTiming")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return data from performance timing")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForFunction")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for function returns true")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should pass arguments and wait for function returns true")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitToHide")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for hidden element")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for hidden element by XPath")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitNumberOfVisibleElements")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for a specified number of elements on the page")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for a specified number of elements on the page using a css selector")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for a specified number of elements which are not yet attached to the DOM")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#moveCursorTo")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should trigger hover event")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not trigger hover event because of the offset is beyond the element")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#switchToNextTab, #switchToPreviousTab, #openNewTab, #closeCurrentTab, #closeOtherTabs, #grabNumberOfOpenTabs")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should only have 1 tab open when the browser starts and navigates to the first page")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to next tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should assert when there is no ability to switch to next tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should close current tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should close other tabs")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open new tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to previous tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should assert when there is no ability to switch to previous tab")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("popup : #acceptPopup, #seeInPopup, #cancelPopup, #grabPopupText")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should accept popup window")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should accept popup window (using default popup action type)")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should cancel popup")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check text in popup")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab text from popup")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return null if no popup is visible (do not throw an error)")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeNumberOfElements")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return 1 as count")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#switchTo")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should switch reference to iframe content")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return error if iframe selector is invalid")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return error if iframe selector is not iframe")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return to parent frame given a null locator")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeInSource, #grabSource")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check for text to be in HTML source")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab the source")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeTitleEquals")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check that title is equal to provided one")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeTextEquals")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check text is equal to provided one")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#_locateClickable")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should locate a button to click")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not locate a non-existing checkbox using _locateClickable")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#_locateCheckable")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should locate a checkbox")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#_locateFields")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should locate a field")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not locate a non-existing field")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("check fields: #seeInField, #seeCheckboxIsChecked, ...")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should throw error if field is not empty")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check values in checkboxes")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check values with boolean")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check values in radio")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check values in select")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check for empty select field")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check for select multiple field")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#pressKey, #pressKeyDown, #pressKeyUp")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be able to send special keys to element")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should use modifier key based on operating system")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should show correct numpad or punctuation key when Shift modifier is active")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should show correct number key when Shift modifier is active")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForEnabled")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for input text field to be enabled")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for input text field to be enabled by xpath")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for a button to be enabled")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForText")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for text after load body")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForValue")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for expected value for given locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for expected value for given css locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for expected value for given xpath locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should only wait for one of the matching elements to contain the value given xpath locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should only wait for one of the matching elements to contain the value given css locator")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#grabHTMLFrom")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should grab inner html from an element using xpath query")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab inner html from an element using id query")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab inner html from multiple elements")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab inner html from within an iframe")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#grabBrowserLogs")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should grab browser logs")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab browser logs across pages")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#dragAndDrop")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("Drag item from source to target (no iframe) @dragNdrop")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("Drag and drop from within an iframe")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#switchTo frame")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should switch to frame using name")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to root frame")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to frame using frame number")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#dragSlider")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should drag scrubber to given position")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#uncheckOption")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should uncheck option that is currently checked")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should NOT uncheck option that is NOT currently checked")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#grabElementBoundingRect")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should get the element bounding rectangle")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should get the element width")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should get the element height")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#handleDownloads")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should dowload file")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForClickable")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for clickable")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for clickable by XPath")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for disabled element")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for disabled element by XPath")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for element not in viewport by top")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for element not in viewport by bottom")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for element not in viewport by left")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for element not in viewport by right")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for overlapping element")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should pass if element change class")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail if element change class and not clickable")])])])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("Puppeteer (remote browser)")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("#_startBrowser")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should throw an exception when endpoint is unreachable")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should clear any prior existing pages on remote browser")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/helper/TestCafe_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/helper/TestCafe_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("TestCafe")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("open page : #amOnPage")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should open main page of configured site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open any page of configured site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open absolute url")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForFunction")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for function returns true")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should pass arguments and wait for function returns true")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/helper/WebDriver_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/helper/WebDriver_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("WebDriver")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("open page : #amOnPage")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should open main page of configured site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open any page of configured site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open absolute url")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("see text : #see")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should fail when text is not on site")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("check fields: #seeInField, #seeCheckboxIsChecked, ...")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should throw error if field is not empty")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check values in checkboxes")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check values with boolean")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check values in radio")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check values in select")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check for empty select field")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check for select multiple field")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return error when element has no value attribute")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("Force Right Click: #forceRightClick")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("it should forceRightClick")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("it should forceRightClick by locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("it should forceRightClick by locator and context")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#pressKey, #pressKeyDown, #pressKeyUp")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be able to send special keys to element")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should use modifier key based on operating system")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should show correct numpad or punctuation key when Shift modifier is active")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should show correct number key when Shift modifier is active")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeInSource, #grabSource")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check for text to be in HTML source")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab the source")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab the innerHTML for an element")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeTitleEquals")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check that title is equal to provided one")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeTextEquals")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check text is equal to provided one")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check text is not equal to empty string of element text")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForFunction")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for function returns true")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should pass arguments and wait for function returns true")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForEnabled")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for input text field to be enabled")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for input text field to be enabled by xpath")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for a button to be enabled")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForValue")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for expected value for given locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for expected value for given css locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for expected value for given xpath locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should only wait for one of the matching elements to contain the value given xpath locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should only wait for one of the matching elements to contain the value given css locator")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitNumberOfVisibleElements")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for a specified number of elements on the page")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should be no [object Object] in the error message")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for a specified number of elements on the page using a css selector")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for a specified number of elements which are not yet attached to the DOM")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForVisible")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be no [object Object] in the error message")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForInvisible")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be no [object Object] in the error message")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for a specified element to be invisible")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#moveCursorTo")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should trigger hover event")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not trigger hover event because of the offset is beyond the element")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#switchToNextTab, #switchToPreviousTab, #openNewTab, #closeCurrentTab, #closeOtherTabs, #grabNumberOfOpenTabs")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should only have 1 tab open when the browser starts and navigates to the first page")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to next tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should assert when there is no ability to switch to next tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should close current tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should close other tabs")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open new tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to previous tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should assert when there is no ability to switch to previous tab")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("popup : #acceptPopup, #seeInPopup, #cancelPopup")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should accept popup window")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should cancel popup")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check text in popup")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab text from popup")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return null if no popup is visible (do not throw an error)")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForText")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return error if not present")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return error if waiting is too small")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeNumberOfElements")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return 1 as count")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#switchTo")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should switch reference to iframe content")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return error if iframe selector is invalid")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return error if iframe selector is not iframe")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return to parent frame given a null locator")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("click context")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should click on inner text")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click on input in inner element")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click by accessibility_id")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("window size #resizeWindow")]),e._v(" "),o("ul",[o("li",[o("p",[e._v("✔️ "),o("code",[e._v("should set initial window size")])])]),e._v(" "),o("li",[o("p",[e._v("✔️ "),o("code",[e._v("should set window size on new session")])])]),e._v(" "),o("li",[o("p",[e._v("✔️ "),o("code",[e._v("should resize window to specific dimensions")]),e._v(" "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/59ded499e787cdd32e7c4f7ad965c98a20b501ec/test/helper/WebDriver_test.js#L786",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/59ded499e787cdd32e7c4f7ad965c98a20b501ec/test/helper/WebDriver_test.js#L786",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/f9c655b79852df30e188176a457c240fa6cb4c75/test/helper/WebDriver_test.js#L786",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/b6f01ba546c821ea05a8ea8e2185155f7f0ebfcf/test/helper/WebDriver_test.js#L786",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/f114b323d09f8f68b55595ad89d5eecaba309411/test/helper/WebDriver_test.js#L786",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/4a6ef74e7e8e367de29d261475d939e66b9b8536/test/helper/WebDriver_test.js#L786",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/dfa8c88f30a3dfa714f43f4932f8b38643d0b43d/test/helper/WebDriver_test.js#L809",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/85df33744833444ca2dd19b30947726b2906d68a/test/helper/WebDriver_test.js#L809",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/b201e460f351f415b8f268cbaa2a56e6f2df95e7/test/helper/WebDriver_test.js#L809",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/987cf85da8de8464f54b463c3c979e4af19a697d/test/helper/WebDriver_test.js#L809",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/bc736c915f4d071cd0eaba6696f048d10e515ce6/test/helper/WebDriver_test.js#L809",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/96278920e6312f2d6c1ed5569d40fa9039a1d796/test/helper/WebDriver_test.js#L809",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/b7bc6cdd8b6550284e50ecc0886dd1dfb9972a6b/test/helper/WebDriver_test.js#L809",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/8c3e79fccf01ab2d3da8b2d6ce902d96d8a83265/test/helper/WebDriver_test.js#L809",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/0e5247789852ec4806dc4365d6ce4a96e84494bc/test/helper/WebDriver_test.js#L809",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/8bc6cf9cdb5cdb26eb8b2d97a333c7f1d5a6fa48/test/helper/WebDriver_test.js#L809",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/7e354b75015bd2bdcdcbe41a97e0c74fdbfc45e3/test/helper/WebDriver_test.js#L809",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/fa84f3f91b2d625a2064adac067ac5401714a2e2/test/helper/WebDriver_test.js#L809",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/974f45cbc54367d92f6a87426d115a2fa854fbb6/test/helper/WebDriver_test.js#L809",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/b7ed4181246cf7f0d03e81cd76c0cdb1bb401204/test/helper/WebDriver_test.js#L809",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/18ff28932c3bc2ef5513a6074c5541a383315b22/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/7df680264b6b0d079651d7cabb818926e53d494b/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/ba86940746ef8c5d37506ff405c2f6f6ee488241/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/52282851b4f4582a1aa7091ebb1a8628ffafcee2/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/41edf4dfb10586d405eee363daf04814342c955c/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/e4dd9a2f1bbf92249ca54b6982a37f1cd45a0be8/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/41936638272091400d4d239769300bd730e5b108/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/63ed1f1d9b1e3a80dffe6fc5f2da50b44e291d6c/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/4a31d20ae19522cc250120f5e4ee4bdf7e0dc455/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/10c7443ae71f32d5ff8c5426f55e4ea2efc194b8/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/a1c9a18ab78d28b3284eba01ed64e00714fcd7b0/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/a7f9f41fc65a2e316730feadd2ed797caefe0b53/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/9c839bd9ab311fa4d92fb01fda29322bbd0982d1/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/37e5ae857521c3f92553d3bde3206e8640c01aba/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/29b942fba620ed48423fc5d4d799c8d49b28273a/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d1686fb303ee46bb5c1e5f52373167062225a5a9/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/b2affe824f31fc565d0f92d8cdc1471e660611f4/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/416cd2cd3b4c6ec439a4e085a1ccc20a6eb10326/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/9808e71c4ac7c6798f1f2dd54dd6be3d7e7c4a91/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/598394b1b7498738fbcb495617b756ab48ea6af5/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/ef5c8da6b66bff845a4a37a1ab0c69f3c46ffb65/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/5164f0090748d2eca00c152d82a55338ac1e21ec/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/85fe5397629172c36cd70e35bd4c14bb6746a832/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/265dcb3a44f2fea26351992728a4f31bc3249290/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/22f28d62df741a9dbf0e9b2e35d27d0dcbc98024/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/4825f53e0cc308c57bf6e55d9aed7da58bc99161/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠ "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/12d55f9271591c85f95fa6d017f30b5f9922aa33/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠")])]),e._v(" "),o("li",[o("p",[o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/helper/WebDriver_test.js#L794",target:"_blank",rel:"noopener noreferrer"}},[o("s",[e._v("should resize window to maximum screen dimensions")]),o("OutboundLink")],1),e._v(" ⚠️ "),o("em",[e._v("skipped")])])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("SmartWait")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for element to appear")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for clickable element appear")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for clickable context to appear")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for text context to appear")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should work with grabbers")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#_locateClickable")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should locate a button to click")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not locate a non-existing checkbox")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#_locateCheckable")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should locate a checkbox")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not locate a non-existing checkbox")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#_locateFields")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should locate a field")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not locate a non-existing field")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab browser logs")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab browser logs across pages")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#dragAndDrop")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("Drag item from source to target (no iframe) @dragNdrop")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("Drag and drop from within an iframe")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#switchTo frame")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should switch to frame using name")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to root frame")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to frame using frame number")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#AttachFile")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should attach to regular input element")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should attach to invisible input element")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#dragSlider")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should drag scrubber to given position")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#uncheckOption")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should uncheck option that is currently checked")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should NOT uncheck option that is NOT currently checked")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("allow back and forth between handles: #grabAllWindowHandles #grabCurrentWindowHandle #switchToWindow")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should open main page of configured site, open a popup, switch to main page, then switch to popup, close popup, and go back to main page")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForClickable")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for clickable")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for clickable by XPath")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for disabled element")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for disabled element by XPath")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for element not in viewport by top")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for element not in viewport by bottom")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for element not in viewport by left")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for element not in viewport by right")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for overlapping element")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("GeoLocation")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should set the geoLocation")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#grabElementBoundingRect")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should get the element size")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should get the element width")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should get the element height")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#scrollIntoView")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should scroll element into viewport")])])])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("WebDriver - Basic Authentication")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("open page : #amOnPage")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be authenticated")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/helper/WebDriverIO_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/helper/WebDriverIO_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("WebDriverIO")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("open page : #amOnPage")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should open main page of configured site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open any page of configured site")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open absolute url")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("see text : #see")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should fail when text is not on site")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("check fields: #seeInField, #seeCheckboxIsChecked, ...")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should throw error if field is not empty")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check values in checkboxes")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check values with boolean")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check values in radio")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check values in select")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check for empty select field")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check for select multiple field")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#pressKey")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be able to send special keys to element")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForClickable")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for clickable")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for clickable by XPath")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for disabled element")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for disabled element by XPath")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for element not in viewport by top")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for element not in viewport by bottom")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for element not in viewport by left")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for element not in viewport by right")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail for overlapping element")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should pass if element change class")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail if element change class and not clickable")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeInSource, #grabSource")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check for text to be in HTML source")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab the source")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeTitleEquals")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check that title is equal to provided one")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeTextEquals")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check text is equal to provided one")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForFunction")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for function returns true")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should pass arguments and wait for function returns true")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForEnabled")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for input text field to be enabled")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for input text field to be enabled by xpath")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for a button to be enabled")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForValue")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for expected value for given locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for expected value for given css locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for expected value for given xpath locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should only wait for one of the matching elements to contain the value given xpath locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should only wait for one of the matching elements to contain the value given css locator")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitNumberOfVisibleElements")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for a specified number of elements on the page")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should be no [object Object] in the error message")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for a specified number of elements on the page using a css selector")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for a specified number of elements which are not yet attached to the DOM")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForVisible")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be no [object Object] in the error message")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for a specified element to be visible")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForInvisible")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be no [object Object] in the error message")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for a specified element to be invisible")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#moveCursorTo")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should trigger hover event")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not trigger hover event because of the offset is beyond the element")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#switchToNextTab, #switchToPreviousTab, #openNewTab, #closeCurrentTab, #closeOtherTabs, #grabNumberOfOpenTabs")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should only have 1 tab open when the browser starts and navigates to the first page")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to next tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should assert when there is no ability to switch to next tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should close current tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should close other tabs")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open new tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to previous tab")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should assert when there is no ability to switch to previous tab")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("popup : #acceptPopup, #seeInPopup, #cancelPopup")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should accept popup window")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should cancel popup")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check text in popup")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab text from popup")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return null if no popup is visible (do not throw an error)")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#waitForText")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return error if not present")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return error if waiting is too small")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#seeNumberOfElements")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return 1 as count")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#switchTo")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should switch reference to iframe content")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return error if iframe selector is invalid")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return error if iframe selector is not iframe")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return to parent frame given a null locator")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("click context")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should click on inner text")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click on input in inner element")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click by aria-label")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click by title")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click by aria-labelledby")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should click by accessibility_id")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("window size #resizeWindow")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should set initial window size")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should resize window to specific dimensions")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should resize window to maximum screen dimensions")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("SmartWait")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wait for element to appear")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for clickable element appear")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for clickable context to appear")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should wait for text context to appear")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should work with grabbers")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#_locateClickable")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should locate a button to click")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not locate a non-existing checkbox")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#_locateCheckable")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should locate a checkbox")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not locate a non-existing checkbox")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#_locateFields")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should locate a field")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not locate a non-existing field")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#grabBrowserLogs")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should grab browser logs")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should grab browser logs across pages")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#dragAndDrop")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("Drag item from source to target (no iframe) @dragNdrop")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("Drag and drop from within an iframe")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#switchTo frame")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should switch to frame using name")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to root frame")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should switch to frame using frame number")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/rest/ApiDataFactory_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/rest/ApiDataFactory_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("ApiDataFactory")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("create and cleanup records")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should create a new post")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create a new post with predefined field")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should obtain id by function")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should update request with onRequest")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("can use functions to set factories")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should cleanup created data")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create multiple posts and cleanup after")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create with different api")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not remove records if cleanup:false")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should send default headers")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/rest/REST_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/rest/REST_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("REST")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("basic requests")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should send GET requests")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should send PATCH requests: payload format = json")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should send PATCH requests: payload format = form urlencoded")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should send POST requests: payload format = json")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should send POST requests: payload format = form urlencoded")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should send PUT requests: payload format = json")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should send PUT requests: payload format = form urlencoded")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should send DELETE requests")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should update request with onRequest")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should set timeout for the request")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("headers")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should send request headers")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should set request headers")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should set Content-Type header if data is string and Content-Type is omitted")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should respect any passsed in Content-Type header")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("_url autocompletion")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should not prepend base url, when url is absolute")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should prepend base url, when url is not absolute")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v('should prepend base url, when url is not absolute, and "http" in request')])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/runner/allure_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/runner/allure_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("CodeceptJS Allure Plugin")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should enable allure reports")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create xml file when assert message has ansi symbols")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should report skipped features")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should report BeforeSuite errors when executing via run command")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should report BeforeSuite errors when executing via run-workers command")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/runner/bdd_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/runner/bdd_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("BDD Gherkin")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should run feature files")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should print substeps in debug mode")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should print events in verbose mode")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should obfuscate secret substeps in debug mode")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run feature with examples files")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run feature with table and examples files")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run feature with tables")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run feature with long strings")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run feature by file name")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run feature by scenario name")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run feature by tag name")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run scenario by tag name")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run scenario outline by tag")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run scenario and scenario outline by tags")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should show all available steps")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should generate snippets for missing steps")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not generate duplicated steps")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/runner/before_failure_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/runner/before_failure_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Failure in before")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should skip tests that are skipped because of failure in before hook")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should skip tests correctly with grep options")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should trigger skipped events")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/runner/bootstrap_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/runner/bootstrap_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("CodeceptJS Bootstrap and Teardown")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should run bootstrap")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run teardown")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run async bootstrap")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run bootstrap/teardown as object")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run async bootstrap function without args")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run async bootstrap function with args")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail with code 1 when test failed and async bootstrap function without args")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail with code 1 when test failed and async bootstrap function with args")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail with code 1 when async bootstrap function without args failed")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail with code 1 when async bootstrap function with args failed")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail with code 1 when raise exceptin in the test file and async bootstrap function with args")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail with code 1 when raise exceptin in the test file and async bootstrap function without args")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run async bootstrap/teardown with args")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run async bootstrap/teardown without args")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail with code 1 when test failed and async bootstrap/teardown function with args")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail with code 1 when test failed and async bootstrap/teardown function without args")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail with code 1 when async bootstrap with args failed and not call teardown")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fail with code 1 when async bootstrap without args failed and not call teardown")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/runner/codecept_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/runner/codecept_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("CodeceptJS Runner")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be executed in current dir")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should be executed with glob")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should be executed with config path")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should show failures and exit with 1 on fail")])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("grep")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("filter by scenario tags")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("filter by scenario tags #2")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("filter by feature tags")])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v('without "invert" option')]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should filter by scenario tags")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should filter by scenario tags #2")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should filter by feature tags")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v('with "invert" option')]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should filter by scenario tags")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should filter by scenario tags #2")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should filter by feature tags")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should filter by feature tags")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run hooks")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run hooks from suites")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run hooks from suites (in different order)")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run different types of scenario")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run dynamic config")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run dynamic config with profile")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run dynamic config with profile 2")])])])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("with require parameter")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be executed with module when described")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should be executed with several modules when described")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not be executed without module when not described")])])])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("Codeceptjs Events")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should fire events with only passing tests")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fire events with passing and failing tests")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/runner/comment_step_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/runner/comment_step_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("CodeceptJS commentStep plugin")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should print nested steps when global var comments used")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should print nested steps when local var comments used")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/runner/definitions_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/runner/definitions_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Definitions")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Static files")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should have internal object that is available as variable codeceptjs")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("def should create definition file")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("def should create definition file with correct page def")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("def should create definition file given a config file")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("def should create definition file with support object")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("def should create definition file with inject which contains support objects")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("def should create definition file with inject which contains I object")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("def should create definition file with inject which contains I object from helpers")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("def should create definition file with callback params")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/runner/dry_run_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/runner/dry_run_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("dry-run command")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be executed with config path")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should list all tests")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not run actual steps")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not run helper hooks")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should display meta steps and substeps")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run feature files")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should print substeps in debug mode")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run tests with different data")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should display meta steps and substeps")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should work with inject() keyword")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should inject page objects via proxy")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/runner/interface_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/runner/interface_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("CodeceptJS Interface")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should rerun flaky tests")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should rerun retried steps")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not propagate retries to non retried steps")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should use retryFailedStep plugin for failed steps")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not retry wait* steps in retryFailedStep plugin")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not retry steps if retryFailedStep plugin disabled")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should include grep option tests")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run tests with different data")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run all tests with data of array by only")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run all tests with data of generator by only")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should execute expected promise chain")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should display meta steps and substeps")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should work with inject() keyword")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should inject page objects via proxy")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/runner/list_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/runner/list_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("list commands")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("list should print actions")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/runner/pageobject_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/runner/pageobject_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("CodeceptJS Interface")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should inject page objects by class")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should inject page objects by class which nested base clas")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/runner/run_multiple_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/runner/run_multiple_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("CodeceptJS Multiple Runner")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should execute one suite with browser")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should execute all suites")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should replace parameters")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should execute multiple suites")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should execute multiple suites with selected browsers")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should print steps")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should pass grep to configuration")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should pass grep invert to configuration")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should pass tests to configuration")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run chunks")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run features in parallel")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run features & tests in parallel")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run only tests in parallel")])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("bootstrapAll and teardownAll")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be executed from async function in config")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should be executed from function in config")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should be executed from function in file")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should be executed from object in file")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("with require parameter")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be executed with module when described")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should be executed with several module when described")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not be executed without module when not described")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/runner/run_rerun_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/runner/run_rerun_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("run-rerun command")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should display count of attemps")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should display 2 success count of attemps")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should display error if minSuccess more than maxReruns")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should display errors if test is fail always")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should display success run if test was fail one time of two attepmts and 3 reruns")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/runner/run_workers_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/runner/run_workers_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("CodeceptJS Workers Runner")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should run tests in 3 workers")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should print positive or zero failures with same name tests")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should use grep")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should show failures when suite is failing")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should print stdout in debug mode and load bootstrap")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run tests with glob pattern")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should print empty results with incorrect glob pattern")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should retry test")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create output folder with custom name")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/runner/session_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/runner/session_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("CodeceptJS session")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should run with 3 sessions")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run session defined before executing")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should run all session tests")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/runner/todo_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/runner/todo_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Todo")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should skip test with todo")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should skip inject skipinfo to todo test")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should correctly pass custom opts for todo test")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/runner/translation_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/runner/translation_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Translation")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("Should run translated test file")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/runner/within_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/runner/within_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("CodeceptJS within")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should execute if no generators")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should execute with async/await. Await is first in order")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should execute with async/await. Await is second in order")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/actor_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/actor_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Actor")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should take all methods from helpers and built in")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return promise")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should produce step events")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should retry failed step with #retry")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should retry once step with #retry")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should print handle failed steps")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/assert_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/assert_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Assertion")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should handle asserts")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should handle negative asserts")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/assert/empty_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/assert/empty_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("empty assertion")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check for something to be empty")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check for something not to be empty")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should provide nice assert error message")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should provide nice negate error message")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/assert/equal_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/assert/equal_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("equal assertion")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check for equality")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check for something not to be equal")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should provide nice assert error message")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should provide nice negate error message")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/assert/include_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/assert/include_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("equal assertion")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should check for inclusion")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check !include")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should provide nice assert error message")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should provide nice negate error message")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/bdd_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/bdd_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("BDD")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should parse gherkin input")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should load step definitions")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should contain tags")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should load step definitions")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should allow failed steps")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should work with async functions")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should execute scenarios step-by-step")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should match step with params")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should use shortened form for step definitions")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should attach before hook for Background")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should execute scenario outlines")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should provide a parsed DataTable")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/config_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/config_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Config")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be created")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should be completely reset")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("can be updated")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should use config hooks to enhance configs")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/container_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/container_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Container")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("#translation")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should create empty translation")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create Russian translation")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create Italian translation")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create French translation")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#helpers")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return all helper with no args")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return helper by name")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#support")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return all support objects")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should support object by name")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#plugins")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return all plugins")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should get plugin by name")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#create")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should create container with helpers")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should always create I")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should load DI and return a reference to the module")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should load I from path and execute _init")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should load DI includes provided as require paths")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should load DI and inject I into PO")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should load DI and inject custom I into PO")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should load DI includes provided as objects")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should load DI includes provided as objects")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#append")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be able to add new helper")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should be able to add new support object")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/data/dataTableArgument_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/data/dataTableArgument_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("DataTableArgument")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should return a 2D array containing each row")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return a 2D array containing each row without the header (first one)")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should return an of object where properties is the header")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/data/table_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/data/table_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("DataTable")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should take an array for creation")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should allow arrays to be added")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not allow an empty array to be added")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not allow an array with more slots than the original to be added")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not allow an array with less slots than the original to be added")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should filter an array")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should filter an array with skips")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/data/ui_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/data/ui_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("ui")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Data")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("can add a tag to all scenarios")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("can add a timout to all scenarios")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("can add retries to all scenarios")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("can expect failure for all scenarios")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("can expect a specific error for all scenarios")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("can configure a helper for all scenarios")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should shows object's toString() method in each scenario's name if the toString() method is overrided")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should shows JSON.stringify() in each scenario's name if the toString() method isn't overrided")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/helper/element_not_found_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/helper/element_not_found_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("ElementNotFound error")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should throw error")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should provide default message")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should use prefix for message")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should use postfix for message")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should stringify locator object")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/helper/FileSystem_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/helper/FileSystem_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("FileSystem")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should be initialized before tests")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should open dirs")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should see file")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should check file contents")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/locator_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/locator_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Locator")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("constructor")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("with string argument")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should create css locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create xpath locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create fuzzy locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create described custom default type locator")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("with object argument")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should create id locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create described custom locator")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("with Locator object argument")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should create id locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should transform CSS to xpath")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should build locator to match element by attr")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should build locator to match element by text")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should build locator to match element by position")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should build complex locator")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should select a by label")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should select child element by name")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should select element by siblings")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should throw an error when xpath with round brackets is nested")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should throw an error when locator with specific position is nested")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not select element by deep nested siblings")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should select element by siblings")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should translate locator to string")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should be able to add custom locator strategy")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should be able to add custom locator strategy")])])])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/output_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/output_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Output")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should allow the output level to be set")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should allow the process to be set")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should allow debug messages when output level >= 2")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/parser_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/parser_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("parser")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("#getParamsToString")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should get params for normal function")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should get params for async function")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/plugin/customLocator_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/plugin/customLocator_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("customLocator")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("add a custom locator by $ -> data-qa")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("add a custom locator by = -> data-test-id")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("add a custom locator with multple char prefix = -> data-test-id")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("add a custom locator with CSS")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/plugin/retryFailedStep_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/plugin/retryFailedStep_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("retryFailedStep")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should retry failed step")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not retry within")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not retry steps with wait*")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not retry steps with amOnPage")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should add custom steps to ignore")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not retry session")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/plugin/screenshotOnFail_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/plugin/screenshotOnFail_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("screenshotOnFail")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should exclude the data driven in failed screenshot file name")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create screenshot on fail")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create screenshot with unique name")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create screenshot with unique name when uuid is null")])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/recorder_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/recorder_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Recorder")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should create a promise")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should execute error handler on error")])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#session")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("can be started saving previous promise chain")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#add")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should add steps to promise")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should not add steps when stopped")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#retry")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should retry failed steps when asked")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should create a chain of retries")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/scenario_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/scenario_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Scenario")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should wrap test function")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should work with async func")])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("events")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should fire events")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fire failed event on error")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should fire failed event on async error")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/steps_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/steps_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("Step")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("has name")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should convert method names for output")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should convert arguments for output")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should provide nice output")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should provide code output")])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#run")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should run step")])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/ui_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/ui_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("ui")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("basic constants")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("context should contain")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("Feature")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("Feature should return featureConfig")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should contain title")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should contain tags")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("retries can be set")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("timeout can be set")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("helpers can be configured")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("Feature can be skipped")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("Feature can be skipped via xFeature")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("Feature are not skipped by default")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("Feature should correctly pass options to suite context")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("Scenario")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("Scenario should return scenarioConfig")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should contain title")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should contain tags")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should dynamically inject dependencies")])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("todo")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should inject skipInfo to opts")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should contain empty description in skipInfo and empty body")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should inject custom opts to opts and without callback")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should inject custom opts to opts and with callback")])])])])])])])])]),e._v(" "),o("p",[e._v("📝 "),o("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/d60dde173b5aecc06e45de0a6b86a43dec69f8ef/test/unit/utils_test.js",target:"_blank",rel:"noopener noreferrer"}},[e._v("test/unit/utils_test.js"),o("OutboundLink")],1)]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("utils")]),e._v(" "),o("ul",[o("li",[e._v("📎 "),o("strong",[e._v("#fileExists")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("exists")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("not exists")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#getParamNames")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("fn#1")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("fn#2")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should handle single-param arrow functions with omitted parens")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should handle trailing comma")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#methodsOfObject")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should get methods")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#ucfirst")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should capitalize first letter")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#beautify")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should beautify JS code")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#xpathLocator")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("combines xpaths")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("converts string to xpath literal")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#replaceValueDeep")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("returns updated object")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("do not replace unexisting value")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("replace simple value")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("replace simple falsy value")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("replace value in array of objects")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("replace simple value deep in object")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("replace object value")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#getNormalizedKeyAttributeValue")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("should normalize key (alias) to key attribute value")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("should normalize modifier key based on operating system")])])])]),e._v(" "),o("li",[e._v("📎 "),o("strong",[e._v("#screenshotOutputFolder")]),e._v(" "),o("ul",[o("li",[e._v("✔️ "),o("code",[e._v("returns the joined filename for filename only")])]),e._v(" "),o("li",[e._v("✔️ "),o("code",[e._v("returns the given filename for absolute one")])])])])])])])])}),[],!1,null,null,null);o.default=_.exports}}]); \ No newline at end of file diff --git a/assets/js/113.b077fa58.js b/assets/js/113.b077fa58.js new file mode 100644 index 00000000..16952390 --- /dev/null +++ b/assets/js/113.b077fa58.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[113],{413:function(t,a,s){"use strict";s.r(a);var e=s(14),n=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("p",[t._v("🚀 CodeceptJS 3 is out now. Install it:")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v("npm i codeceptjs\n")])])]),a("ul",[a("li",[a("a",{attrs:{href:"https://github.com/Codeception/CodeceptJS/blob/codeceptjs-v3.0/CHANGELOG.md#300-beta",target:"_blank",rel:"noopener noreferrer"}},[t._v("COMPLETE CHANGELOG"),a("OutboundLink")],1)]),t._v(" "),a("li",[a("a",{attrs:{href:"https://github.com/Codeception/CodeceptJS/tree/codeceptjs-v3.0/docs",target:"_blank",rel:"noopener noreferrer"}},[t._v("Documentation"),a("OutboundLink")],1)])]),t._v(" "),a("p",[t._v("After installing a new version, run "),a("code",[t._v("codecept3-upgrade")]),t._v(" which is described below:")]),t._v(" "),a("hr"),t._v(" "),a("p",[t._v("CodeceptJS 3.0 is a new version of CodeceptJS with some breaking changes included.\nYou should update your project following this guide to ensure that everything works correctly.")]),t._v(" "),a("h3",{attrs:{id:"_1️⃣-syntax-change"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_1️⃣-syntax-change"}},[t._v("#")]),t._v(" 1️⃣ Syntax Change")]),t._v(" "),a("p",[t._v("CodeceptJS 3.0 introduced a new syntax for declaring tests, instead of:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'title'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" loginPage")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("we use a new way of passing arguments into a test, via destruction:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'title'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" loginPage "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("This works similarly to "),a("code",[t._v("inject()")]),t._v(" command. This change was done to unify accessing "),a("a",{attrs:{href:"https://codecept.io/pageobjects/#dependency-injection",target:"_blank",rel:"noopener noreferrer"}},[t._v("dependency injection container"),a("OutboundLink")],1),t._v(", and to provide better TypeScript support.")]),t._v(" "),a("blockquote",[a("p",[t._v("If you use BDD-style project with Gherkin, no changes needed for this step.")])]),t._v(" "),a("p",[t._v("To upgrade your project, you don't need to change manually all your tests.")]),t._v(" "),a("p",[t._v("💪 "),a("strong",[t._v("Use "),a("a",{attrs:{href:"https://www.npmjs.com/package/codecept3-upgrade",target:"_blank",rel:"noopener noreferrer"}},[t._v("codecept3-upgrade tool"),a("OutboundLink")],1),t._v(" to perform the migration")]),t._v(". Use it carefully, as it updates your current code.")]),t._v(" "),a("p",[t._v("To upgrade your codebase, commit all your changes, and switch to a new branch.\nRun upgrade script (even without installing) for a directory where you have your tests:")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v("npx codecept3-upgrade tests\n")])])]),a("p",[t._v("Review the changes in Git Diff and try to execute tests using CodeceptJS 3.0")]),t._v(" "),a("h3",{attrs:{id:"_2️⃣-grabbers-signature-change"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_2️⃣-grabbers-signature-change"}},[t._v("#")]),t._v(" 2️⃣ Grabbers signature change")]),t._v(" "),a("p",[t._v("There were confusion and inconsistency across grab* methods. What they will return if multiple elements are found? A single element or an array? This was the problem as the format was dependent on a page content.")]),t._v(" "),a("p",[t._v("In 3.0 we decided to make all current grab* methods to return a single value only. While we add new methods grab**FromAll that return an array.")]),t._v(" "),a("p",[t._v("For instance, "),a("code",[t._v("grabTextFrom")]),t._v(" will always return a single text value, while "),a("code",[t._v("grabTextFromAll")]),t._v(" will return an array of values:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabTextFrom")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.username'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john'")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabTextFromAll")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.username'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'claudia'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'bill'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),a("p",[t._v("Please update parts in your project where you rely on grab* methods to return an array.")]),t._v(" "),a("table",[a("thead",[a("tr",[a("th",[t._v("Single Value")]),t._v(" "),a("th",[t._v("Multiple Values")])])]),t._v(" "),a("tbody",[a("tr",[a("td",[t._v("✋"),a("code",[t._v("grabTextFrom")])]),t._v(" "),a("td",[t._v("🙌 "),a("code",[t._v("grabTextFromAll")])])]),t._v(" "),a("tr",[a("td",[t._v("✋"),a("code",[t._v("grabValueFrom")])]),t._v(" "),a("td",[t._v("🙌 "),a("code",[t._v("grabValueFromAll")])])]),t._v(" "),a("tr",[a("td",[t._v("✋ "),a("code",[t._v("grabAttributeFrom")])]),t._v(" "),a("td",[t._v("🙌"),a("code",[t._v("grabAttributeFromAll")])])]),t._v(" "),a("tr",[a("td",[t._v("✋ "),a("code",[t._v("grabHTMLFrom")])]),t._v(" "),a("td",[t._v("🙌 "),a("code",[t._v("grabHTMLFromAll")])])]),t._v(" "),a("tr",[a("td",[t._v("✋ "),a("code",[t._v("grabCssPropertyFrom")])]),t._v(" "),a("td",[t._v("🙌 "),a("code",[t._v("grabCssPropertyFromAll")])])])])]),t._v(" "),a("blockquote",[a("p",[t._v("Single-value "),a("code",[t._v("grab*From")]),t._v(" will throw error when no data was matched, while "),a("code",[t._v("grab*FromAll")]),t._v(" will return array.")])]),t._v(" "),a("h3",{attrs:{id:"_3️⃣-bootstrap-teardown-changed"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_3️⃣-bootstrap-teardown-changed"}},[t._v("#")]),t._v(" 3️⃣ Bootstrap / Teardown Changed")]),t._v(" "),a("p",[a("code",[t._v("async/await")]),t._v(" paradigm changed the way we write asynchronous code in NodeJS.\nHowever, bootstrap functions were created to use old-style methods of passing "),a("code",[t._v("done")]),t._v(" callback inside.")]),t._v(" "),a("p",[t._v("In 3.0 we decided to completely change the way async bootstrap is performed and replace all it with async/await functions:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// before")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("bootstrap")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("done")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n server"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("start")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("then")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("done"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// after")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("bootstrap")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" server"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("start")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("Passing a string as bootstrap function (to require a function from external file) is also not supported:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// before")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("bootstrap")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./server_start.js'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// after")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("bootstrap")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./server_start.js'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),a("p",[t._v("The same rules are applied to teardown, bootstrapAll, teardownAll.")]),t._v(" "),a("h3",{attrs:{id:"_4️⃣-locator-detection-heuristic-change"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_4️⃣-locator-detection-heuristic-change"}},[t._v("#")]),t._v(" 4️⃣ Locator Detection Heuristic Change")]),t._v(" "),a("p",[t._v("In 3.0 we added a new rule to auto-detect CSS locator. If a locator starts with "),a("code",[t._v("[")]),t._v(" parser will use it as a CSS locator, without trying to match value by text.")]),t._v(" "),a("ul",[a("li",[t._v("Previous behavior: I.click('[user]') - will try to search for a link with "),a("code",[t._v("[user]")]),t._v(" text, if no found - take "),a("code",[t._v("[user]")]),t._v(" as CSS locator")]),t._v(" "),a("li",[t._v("Current behavior: I.click('[user]') - will check only for CSS locator "),a("code",[t._v("[user]")])])]),t._v(" "),a("h3",{attrs:{id:"_5️⃣-improved-parallel-execution-with-workers"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#_5️⃣-improved-parallel-execution-with-workers"}},[t._v("#")]),t._v(" 5️⃣ Improved Parallel Execution with Workers")]),t._v(" "),a("p",[t._v("CodeceptJS has two parallel execution modes:")]),t._v(" "),a("ul",[a("li",[t._v("classical "),a("code",[t._v("run-multiple")]),t._v(" which spawns independent CodeceptJS processes on system level.")]),t._v(" "),a("li",[t._v("threaded "),a("code",[t._v("run-workers")]),t._v(" which uses NodeJS workers instead of subprocesses.")])]),t._v(" "),a("p",[t._v("Workers are faster, they can communicate with parent thread. Unfortunately, "),a("code",[t._v("run-workers")]),t._v(" was not as efficient as "),a("code",[t._v("run-multiple")]),t._v(" because there was no way of declaring sophisticated configs for parallel execution. For instance, running tests in 4 threads in 2 browsers could not be set.")]),t._v(" "),a("p",[t._v("We updated workers API to make them as flexible as possible. You don't even need to put complex logic into config! You can create your own parallel runner and customize it to match your expectations:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// don't initialize workers in constructor")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" workers "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Workers")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" workerConfig"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// split tests by suites in 2 groups")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" testGroups "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" workers"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("createGroupsOfSuites")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" browsers "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'firefox'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'chrome'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" configs "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" browsers"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("browser")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" browser "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" config "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("of")]),t._v(" configs"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("group "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("of")]),t._v(" groupOfTests"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" worker "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" workers"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("spawn")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n worker"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addTests")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("group"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n worker"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addConfig")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("config"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nworkers"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("run")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[a("a",{attrs:{href:"https://github.com/Codeception/CodeceptJS/blob/codeceptjs-v3.0/docs/parallel.md#custom-parallel-execution",target:"_blank",rel:"noopener noreferrer"}},[t._v("Learn more about how you can create a parallel runner"),a("OutboundLink")],1),t._v(".")]),t._v(" "),a("p",[a("code",[t._v("run-multiple")]),t._v(" will still work but it is considered deprecated and won't be supported.")]),t._v(" "),a("h3",{attrs:{id:"webdriverio-helper-removed"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#webdriverio-helper-removed"}},[t._v("#")]),t._v(" WebDriverIO helper removed")]),t._v(" "),a("p",[t._v("WebDriverIO helper supported webdriverio v4 library, which is not maintained anymore. It should be easy to switch to WebDriver helper which supports webdriverio v6.")])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/114.7f7a6880.js b/assets/js/114.7f7a6880.js new file mode 100644 index 00000000..c8f7ae11 --- /dev/null +++ b/assets/js/114.7f7a6880.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[114],{416:function(t,e,r){"use strict";r.r(e);var n=r(14),o=Object(n.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("p",[e("a",{attrs:{href:"https://www.youtube.com/watch?v=BRMWstiOTks",target:"_blank",rel:"noopener noreferrer"}},[e("img",{attrs:{src:"http://i3.ytimg.com/vi/BRMWstiOTks/maxresdefault.jpg",alt:""}}),e("OutboundLink")],1)]),t._v(" "),e("h2",{attrs:{id:"an-introduction-getting-started-and-working-with-codeceptjs-puppeteer-eaweekend"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#an-introduction-getting-started-and-working-with-codeceptjs-puppeteer-eaweekend"}},[t._v("#")]),t._v(" "),e("a",{attrs:{href:"https://www.youtube.com/watch?v=BRMWstiOTks",target:"_blank",rel:"noopener noreferrer"}},[t._v("An Introduction, Getting started and working with CodeceptJS & Puppeteer (EAWeekend)"),e("OutboundLink")],1)]),t._v(" "),e("h2",{attrs:{id:"codeceptjs-official-youtube-channel"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#codeceptjs-official-youtube-channel"}},[t._v("#")]),t._v(" "),e("a",{attrs:{href:"https://www.youtube.com/channel/UCEs4030bmtonyDhTHEXa_2g",target:"_blank",rel:"noopener noreferrer"}},[t._v("CodeceptJS Official YouTube Channel"),e("OutboundLink")],1)]),t._v(" "),e("h2",{attrs:{id:"introductory-videos"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#introductory-videos"}},[t._v("#")]),t._v(" "),e("a",{attrs:{href:"https://www.youtube.com/watch?v=FPFG1rBNJ64&list=PLcFXthgti9Lt4SjSvL1ALDg6dOeTC0TvT",target:"_blank",rel:"noopener noreferrer"}},[t._v("Introductory Videos"),e("OutboundLink")],1)]),t._v(" "),e("p",[t._v("Free educational videos provided by our community member "),e("strong",[e("a",{attrs:{href:"http://github.com/ontytoom",target:"_blank",rel:"noopener noreferrer"}},[t._v("@ontytoom"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("ol",[e("li",[e("a",{attrs:{href:"https://www.youtube.com/watch?v=FPFG1rBNJ64",target:"_blank",rel:"noopener noreferrer"}},[t._v("Installation"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://www.youtube.com/watch?v=mdQZjL3h9d0",target:"_blank",rel:"noopener noreferrer"}},[t._v("Creating a Test"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://www.youtube.com/watch?v=s677_6VctjQ",target:"_blank",rel:"noopener noreferrer"}},[t._v("Using Page Objects"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"practical-e2e-testing-with-codeceptjs"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#practical-e2e-testing-with-codeceptjs"}},[t._v("#")]),t._v(" "),e("a",{attrs:{href:"https://www.udemy.com/practical-e2e-testing-with-codeceptjs/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Practical E2E Testing with CodeceptJS"),e("OutboundLink")],1)]),t._v(" "),e("p",[t._v("Udemy course by Luke Beilharz")])])}),[],!1,null,null,null);e.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/12.a1725f6f.js b/assets/js/12.a1725f6f.js new file mode 100644 index 00000000..2f99e5f7 --- /dev/null +++ b/assets/js/12.a1725f6f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[12,6,14,15,18,20,21,24],{239:function(t,e,n){"use strict";n.d(e,"d",(function(){return i})),n.d(e,"a",(function(){return r})),n.d(e,"i",(function(){return a})),n.d(e,"f",(function(){return l})),n.d(e,"g",(function(){return u})),n.d(e,"h",(function(){return c})),n.d(e,"b",(function(){return p})),n.d(e,"e",(function(){return h})),n.d(e,"k",(function(){return d})),n.d(e,"l",(function(){return f})),n.d(e,"c",(function(){return b})),n.d(e,"j",(function(){return m}));n(89);const i=/#.*$/,s=/\.(md|html)$/,r=/\/$/,a=/^[a-z]+:/i;function o(t){return decodeURI(t).replace(i,"").replace(s,"")}function l(t){return a.test(t)}function u(t){return/^mailto:/.test(t)}function c(t){return/^tel:/.test(t)}function p(t){if(l(t))return t;const e=t.match(i),n=e?e[0]:"",s=o(t);return r.test(s)?t:s+".html"+n}function h(t,e){const n=t.hash,s=function(t){const e=t.match(i);if(e)return e[0]}(e);if(s&&n!==s)return!1;return o(t.path)===o(e)}function d(t,e,n){if(l(e))return{type:"external",path:e};n&&(e=function(t,e,n){const i=t.charAt(0);if("/"===i)return t;if("?"===i||"#"===i)return e+t;const s=e.split("/");n&&s[s.length-1]||s.pop();const r=t.replace(/^\//,"").split("/");for(let t=0;t({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}(t);const o=a.sidebar||r.sidebar;if(o){const{base:t,config:n}=function(t,e){if(Array.isArray(e))return{base:"/",config:e};for(const i in e)if(0===(n=t,/(\.html|\/)$/.test(n)?n:n+"/").indexOf(encodeURI(i)))return{base:i,config:e[i]};var n;return{}}(e,o);return n?n.map(e=>function t(e,n,i,s=1){if("string"==typeof e)return d(n,e,i);if(Array.isArray(e))return Object.assign(d(n,e[0],i),{title:e[1]});{s>3&&console.error("[vuepress] detected a too deep nested sidebar group.");const r=e.children||[];return 0===r.length&&e.path?Object.assign(d(n,e.path,i),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,children:r.map(e=>t(e,n,i,s+1)),collapsable:!1!==e.collapsable}}}(e,s,t)):[]}return[]}function b(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function m(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},240:function(t,e,n){},241:function(t,e,n){},242:function(t,e,n){},243:function(t,e,n){},248:function(t,e,n){},249:function(t,e,n){"use strict";n.r(e);var i={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},s=(n(253),n(14)),r=Object(s.a)(i,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=r.exports},250:function(t,e,n){"use strict";n.r(e);var i=n(239),s={props:{item:{required:!0}},computed:{link(){return Object(i.b)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link}},methods:{isExternal:i.f,isMailto:i.g,isTel:i.h,focusoutAction(){this.$emit("focusout")}}},r=(n(252),n(14)),a=Object(r.a)(s,(function(){var t=this,e=t._self._c;return t.isExternal(t.link)?e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.isMailto(t.link)||t.isTel(t.link)?null:"_blank",rel:t.isMailto(t.link)||t.isTel(t.link)?null:"noopener noreferrer"},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),e("OutboundLink")],1):e("router-link",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v(t._s(t.item.text))])}),[],!1,null,"34dbfd23",null);e.default=a.exports},251:function(t,e,n){"use strict";n.r(e);var i=n(267),s=n(261),r=n(239);function a(t,e){return"group"===e.type&&e.children.some(e=>"group"===e.type?a(t,e):"page"===e.type&&Object(r.e)(t,e.path))}var o={name:"SidebarLinks",components:{SidebarGroup:i.default,SidebarLink:s.default},props:["items","depth","sidebarDepth"],data:()=>({openGroupIndex:0}),created(){this.refreshIndex()},watch:{$route(){this.refreshIndex()}},methods:{refreshIndex(){const t=function(t,e){for(let n=0;n-1&&(this.openGroupIndex=t)},toggleGroup(t){this.openGroupIndex=t===this.openGroupIndex?-1:t},isActive(t){return Object(r.e)(this.$route,t.regularPath)}}},l=n(14),u=Object(l.a)(o,(function(){var t=this,e=t._self._c;return t.items.length?e("ul",{staticClass:"sidebar-links"},t._l(t.items,(function(n,i){return e("li",{key:i},["group"===n.type?e("SidebarGroup",{attrs:{item:n,open:i===t.openGroupIndex,collapsable:n.collapsable||n.collapsible,depth:t.depth},on:{toggle:function(e){return t.toggleGroup(i)}}}):e("SidebarLink",{attrs:{sidebarDepth:t.sidebarDepth,item:n}})],1)})),0):t._e()}),[],!1,null,null,null);e.default=u.exports},252:function(t,e,n){"use strict";n(240)},253:function(t,e,n){"use strict";n(241)},254:function(t,e,n){},256:function(t,e,n){"use strict";n(242)},257:function(t,e,n){"use strict";n(243)},258:function(t,e,n){},259:function(t,e,n){},261:function(t,e,n){"use strict";n.r(e);var i=n(239);function s(t,e,n,i){return t("router-link",{props:{to:e,activeClass:"",exactActiveClass:""},class:{active:i,"sidebar-link":!0}},n)}function r(t,e,n,a,o,l=1){return!e||l>o?null:t("ul",{class:"sidebar-sub-headers"},e.map(e=>{const u=Object(i.e)(a,n+"#"+e.slug);return t("li",{class:"sidebar-sub-header"},[s(t,n+"#"+e.slug,e.title,u),r(t,e.children,n,a,o,l+1)])}))}var a={functional:!0,props:["item","sidebarDepth"],render(t,{parent:{$page:e,$site:n,$route:a,$themeConfig:o,$themeLocaleConfig:l},props:{item:u,sidebarDepth:c}}){const p=Object(i.e)(a,u.path),h="auto"===u.type?p||u.children.some(t=>Object(i.e)(a,u.basePath+"#"+t.slug)):p,d="external"===u.type?function(t,e,n){return t("a",{attrs:{href:e,target:"_blank",rel:"noopener noreferrer"},class:{"sidebar-link":!0}},[n,t("OutboundLink")])}(t,u.path,u.title||u.path):s(t,u.path,u.title||u.path,h),f=[e.frontmatter.sidebarDepth,c,l.sidebarDepth,o.sidebarDepth,1].find(t=>void 0!==t),b=l.displayAllHeaders||o.displayAllHeaders;if("auto"===u.type)return[d,r(t,u.children,u.basePath,a,f)];if((h||b)&&u.headers&&!i.d.test(u.path)){return[d,r(t,Object(i.c)(u.headers),u.path,a,f)]}return d}},o=(n(256),n(257),n(14)),l=Object(o.a)(a,void 0,void 0,!1,null,"a68ca4e6",null);e.default=l.exports},266:function(t,e,n){"use strict";n(248)},267:function(t,e,n){"use strict";n.r(e);var i=n(239),s={name:"SidebarGroup",props:["item","open","collapsable","depth"],components:{DropdownTransition:n(249).default},beforeCreate(){this.$options.components.SidebarLinks=n(251).default},methods:{isActive:i.e}},r=(n(266),n(14)),a=Object(r.a)(s,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"sidebar-group",class:[{collapsable:t.collapsable,"is-sub-group":0!==t.depth},"depth-"+t.depth]},[t.item.path?e("router-link",{staticClass:"sidebar-heading clickable",class:{open:t.open,active:t.isActive(t.$route,t.item.path)},attrs:{to:t.item.path},nativeOn:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"open":""}):t._e()]):e("p",{staticClass:"sidebar-heading",class:{open:t.open},on:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"open":""}):t._e()]),t._v(" "),e("DropdownTransition",[t.open||!t.collapsable?e("SidebarLinks",{staticClass:"sidebar-group-items",attrs:{items:t.item.children,sidebarDepth:t.item.sidebarDepth,depth:t.depth+1}}):t._e()],1)],1)}),[],!1,null,null,null);e.default=a.exports},271:function(t,e,n){},276:function(t,e,n){"use strict";n(254)},278:function(t,e,n){"use strict";n(258)},279:function(t,e,n){"use strict";n(259)},281:function(t,e,n){"use strict";n.r(e);var i=n(282),s=n(239),r={components:{NavLink:n(250).default,DropdownLink:i.default},computed:{userNav(){return this.$themeLocaleConfig.nav||this.$site.themeConfig.nav||[]},nav(){const{locales:t}=this.$site;if(t&&Object.keys(t).length>1){const e=this.$page.path,n=this.$router.options.routes,i=this.$site.themeConfig.locales||{},s={text:this.$themeLocaleConfig.selectText||"Languages",ariaLabel:this.$themeLocaleConfig.ariaLabel||"Select language",items:Object.keys(t).map(s=>{const r=t[s],a=i[s]&&i[s].label||r.lang;let o;return r.lang===this.$lang?o=e:(o=e.replace(this.$localeConfig.path,s),n.some(t=>t.path===o)||(o=s)),{text:a,link:o}})};return[...this.userNav,s]}return this.userNav},userLinks(){return(this.nav||[]).map(t=>Object.assign(Object(s.j)(t),{items:(t.items||[]).map(s.j)}))},repoLink(){const{repo:t}=this.$site.themeConfig;return t?/^https?:/.test(t)?t:"https://github.com/"+t:null},repoLabel(){if(!this.repoLink)return;if(this.$site.themeConfig.repoLabel)return this.$site.themeConfig.repoLabel;const t=this.repoLink.match(/^https?:\/\/[^/]+/)[0],e=["GitHub","GitLab","Bitbucket"];for(let n=0;n({open:!1}),props:{item:{required:!0}},computed:{dropdownAriaLabel(){return this.item.ariaLabel||this.item.text}},methods:{toggle(){this.open=!this.open},isLastItemOfArray:(t,e)=>a()(e)===t},watch:{$route(){this.open=!1}}},l=(n(276),n(14)),u=Object(l.a)(o,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"dropdown-wrapper",class:{open:t.open}},[e("button",{staticClass:"dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:t.toggle}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow",class:t.open?"down":"right"})]),t._v(" "),e("DropdownTransition",[e("ul",{directives:[{name:"show",rawName:"v-show",value:t.open,expression:"open"}],staticClass:"nav-dropdown"},t._l(t.item.items,(function(n,i){return e("li",{key:n.link||i,staticClass:"dropdown-item"},["links"===n.type?e("div",{staticClass:"dropdown-item-title"},[t._v(t._s(n.text))]):t._e(),t._v(" "),"links"===n.type?e("ul",{staticClass:"dropdown-subitem-wrapper"},t._l(n.items,(function(i){return e("li",{key:i.link,staticClass:"dropdown-subitem"},[e("NavLink",{attrs:{item:i},on:{focusout:function(e){t.isLastItemOfArray(i,n.items)&&t.isLastItemOfArray(n,t.item.items)&&t.toggle()}}})],1)})),0):e("NavLink",{attrs:{item:n},on:{focusout:function(e){t.isLastItemOfArray(n,t.item.items)&&t.toggle()}}})],1)})),0)])],1)}),[],!1,null,null,null);e.default=u.exports},284:function(t,e,n){"use strict";n.r(e);var i=n(251),s=n(281),r={name:"Sidebar",components:{SidebarLinks:i.default,NavLinks:s.default},props:["items"]},a=(n(278),n(279),n(14)),o=Object(a.a)(r,(function(){var t=this._self._c;return t("aside",{staticClass:"sidebar"},[t("NavLinks"),this._v(" "),this._t("top"),this._v(" "),t("SidebarLinks",{attrs:{depth:0,items:this.items}}),this._v(" "),this._t("bottom")],2)}),[],!1,null,null,null);e.default=o.exports},292:function(t,e,n){"use strict";n(271)}}]); \ No newline at end of file diff --git a/assets/js/13.a6782b38.js b/assets/js/13.a6782b38.js new file mode 100644 index 00000000..9e1e97a4 --- /dev/null +++ b/assets/js/13.a6782b38.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[13,17,19,22,25,26],{239:function(t,e,s){"use strict";s.d(e,"d",(function(){return i})),s.d(e,"a",(function(){return r})),s.d(e,"i",(function(){return a})),s.d(e,"f",(function(){return c})),s.d(e,"g",(function(){return u})),s.d(e,"h",(function(){return l})),s.d(e,"b",(function(){return p})),s.d(e,"e",(function(){return d})),s.d(e,"k",(function(){return h})),s.d(e,"l",(function(){return f})),s.d(e,"c",(function(){return v})),s.d(e,"j",(function(){return _}));s(89);const i=/#.*$/,n=/\.(md|html)$/,r=/\/$/,a=/^[a-z]+:/i;function o(t){return decodeURI(t).replace(i,"").replace(n,"")}function c(t){return a.test(t)}function u(t){return/^mailto:/.test(t)}function l(t){return/^tel:/.test(t)}function p(t){if(c(t))return t;const e=t.match(i),s=e?e[0]:"",n=o(t);return r.test(n)?t:n+".html"+s}function d(t,e){const s=t.hash,n=function(t){const e=t.match(i);if(e)return e[0]}(e);if(n&&s!==n)return!1;return o(t.path)===o(e)}function h(t,e,s){if(c(e))return{type:"external",path:e};s&&(e=function(t,e,s){const i=t.charAt(0);if("/"===i)return t;if("?"===i||"#"===i)return e+t;const n=e.split("/");s&&n[n.length-1]||n.pop();const r=t.replace(/^\//,"").split("/");for(let t=0;t({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}(t);const o=a.sidebar||r.sidebar;if(o){const{base:t,config:s}=function(t,e){if(Array.isArray(e))return{base:"/",config:e};for(const i in e)if(0===(s=t,/(\.html|\/)$/.test(s)?s:s+"/").indexOf(encodeURI(i)))return{base:i,config:e[i]};var s;return{}}(e,o);return s?s.map(e=>function t(e,s,i,n=1){if("string"==typeof e)return h(s,e,i);if(Array.isArray(e))return Object.assign(h(s,e[0],i),{title:e[1]});{n>3&&console.error("[vuepress] detected a too deep nested sidebar group.");const r=e.children||[];return 0===r.length&&e.path?Object.assign(h(s,e.path,i),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,children:r.map(e=>t(e,s,i,n+1)),collapsable:!1!==e.collapsable}}}(e,n,t)):[]}return[]}function v(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function _(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},244:function(t,e){t.exports=function(t){return null==t}},245:function(t,e,s){},246:function(t,e,s){},247:function(t,e,s){},255:function(t,e,s){},262:function(t,e,s){"use strict";s(245)},263:function(t,e,s){var i=s(11),n=s(4),r=s(10);t.exports=function(t){return"string"==typeof t||!n(t)&&r(t)&&"[object String]"==i(t)}},264:function(t,e,s){"use strict";s(246)},265:function(t,e,s){"use strict";s(247)},268:function(t,e,s){"use strict";s.r(e);s(265);var i=s(14),n=Object(i.a)({},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"sidebar"},[e("div",{staticClass:"sidebar-wrapper"},[e("h4",[t._v("More Information")]),t._v(" "),e("p",[e("router-link",{attrs:{to:"/videos"}},[t._v("Videos")])],1),t._v(" "),e("p",[e("router-link",{attrs:{to:"/books"}},[t._v("Books & Posts")])],1),t._v(" "),e("p",[e("router-link",{attrs:{to:"/examples"}},[t._v("Examples")])],1),t._v(" "),t._m(0),t._v(" "),e("hr"),t._v(" "),t._m(1),t._v(" "),t._m(2),t._v(" "),t._m(3),t._v(" "),t._m(4)])])}),[function(){var t=this._self._c;return t("p",[t("a",{attrs:{href:"https://codecept.discourse.group/c/cookbook"}},[this._v("Cookbook →")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://sdclabs.com/codeceptjs?utm_source=codecept.io&utm_medium=right&utm_term=link&utm_campaign=reference"}},[this._v("\n Commercial Services →\n ")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://sdclabs.com/trainings/web-automation-codeceptjs?utm_source=codecept.io&utm_medium=rigth&utm_term=link&utm_campaign=reference"}},[this._v("\n Trainings →\n ")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://testomat.io"}},[this._v("\n Testomat.io →\n ")]),t("br"),this._v(" "),t("small",[t("b",[this._v("Plan your end 2 end tests")]),this._v(", collaborate, synchronize with code & get reports!"),t("br"),this._v("\n Join Testomat.io while it is in beta and get a huge discount!")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://opencollective.com/codeceptjs"}},[this._v("\n Support us via OpenCollective!\n ")])])}],!1,null,"0dc4070a",null);e.default=n.exports},269:function(t,e,s){},270:function(t,e,s){},272:function(t,e,s){"use strict";s.r(e);var i={data:()=>({year:(new Date).getFullYear()})},n=(s(290),s(14)),r=Object(n.a)(i,(function(){var t=this,e=t._self._c;return e("footer",[e("section",[e("div",{staticClass:"col"},[e("h4",[t._v("Docs")]),t._v(" "),e("ul",[e("li",[e("router-link",{attrs:{to:"/quickstart"}},[t._v("Quickstart")])],1),t._v(" "),e("li",[e("router-link",{attrs:{to:"/basics"}},[t._v("Getting Started")])],1),t._v(" "),e("li",[e("router-link",{attrs:{to:"/playwright"}},[t._v("CodeceptJS & Playwright")])],1),t._v(" "),e("li",[e("router-link",{attrs:{to:"/puppeteer"}},[t._v("CodeceptJS & WebDriver")])],1)])]),t._v(" "),t._m(0),t._v(" "),t._m(1),t._v(" "),t._m(2)]),t._v(" "),e("div",{staticClass:"copyright"},[e("h5",[t._v("CodeceptJS - supercharged end 2 end testing framework for NodeJS")]),t._v("\n © "+t._s(t.year)+"\n ")])])}),[function(){var t=this,e=t._self._c;return e("div",{staticClass:"col"},[e("h4",[t._v("Community")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS"}},[t._v("GitHub")])]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/discussions"}},[t._v("GitHub discussions")])]),t._v(" "),e("li",[e("a",{attrs:{href:"https://bit.ly/chat-codeceptjs"}},[t._v("Slack Chat")])]),t._v(" "),e("li",[e("a",{attrs:{href:"https://codecept.discourse.group/"}},[t._v("Forum")])]),t._v(" "),e("li",[e("a",{attrs:{href:"https://twitter.com/codeceptjs"}},[t._v("Twitter")])])])])},function(){var t=this._self._c;return t("div",{staticClass:"col"},[t("h4",{staticClass:"important"},[this._v("Commercial Support")]),this._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://sdclabs.com/codeceptjs?utm_source=codecept.io&utm_medium=footer&utm_term=link&utm_campaign=reference"}},[this._v("Consulting")])]),this._v(" "),t("li",[t("a",{attrs:{href:"https://sdclabs.com/trainings/web-automation-codeceptjs?utm_source=codecept.io&utm_medium=top_menu&utm_term=link&utm_campaign=reference"}},[this._v("Trainings")])]),this._v(" "),t("li",[t("a",{attrs:{href:"https://sdclabs.com/#services"}},[this._v("Hire Engineers")])])])])},function(){var t=this._self._c;return t("div",{staticClass:"col"},[t("a",{attrs:{href:"https://testomat.io"}},[t("h4",[this._v("Try Testomat.io →")]),this._v(" "),t("p",[this._v("Powerful "),t("b",[this._v("Test Case Management")]),this._v(" for CodeceptJS from its authors")])])])}],!1,null,"5616cc4e",null);e.default=r.exports},273:function(t,e,s){"use strict";s.r(e);var i=s(244),n=s.n(i),r=s(239),a={name:"PageEdit",computed:{lastUpdated(){return this.$page.lastUpdated},lastUpdatedText(){return"string"==typeof this.$themeLocaleConfig.lastUpdated?this.$themeLocaleConfig.lastUpdated:"string"==typeof this.$site.themeConfig.lastUpdated?this.$site.themeConfig.lastUpdated:"Last Updated"},editLink(){const t=n()(this.$page.frontmatter.editLink)?this.$site.themeConfig.editLinks:this.$page.frontmatter.editLink,{repo:e,docsDir:s="",docsBranch:i="master",docsRepo:r=e}=this.$site.themeConfig;return t&&r&&this.$page.relativePath?this.createEditLink(e,r,s,i,this.$page.relativePath):null},editLinkText(){return this.$themeLocaleConfig.editLinkText||this.$site.themeConfig.editLinkText||"Edit this page"}},methods:{createEditLink(t,e,s,i,n){if(/bitbucket.org/.test(t)){return(r.i.test(e)?e:t).replace(r.a,"")+"/src"+`/${i}/`+(s?s.replace(r.a,"")+"/":"")+n+`?mode=edit&spa=0&at=${i}&fileviewer=file-view-default`}return(r.i.test(e)?e:"https://github.com/"+e).replace(r.a,"")+"/edit"+`/${i}/`+(s?s.replace(r.a,"")+"/":"")+n}}},o=(s(262),s(14)),c=Object(o.a)(a,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"page-edit"},[t.editLink?e("div",{staticClass:"edit-link"},[e("a",{attrs:{href:t.editLink,target:"_blank",rel:"noopener noreferrer"}},[t._v(t._s(t.editLinkText))]),t._v(" "),e("OutboundLink")],1):t._e(),t._v(" "),t.lastUpdated?e("div",{staticClass:"last-updated"},[e("span",{staticClass:"prefix"},[t._v(t._s(t.lastUpdatedText)+":")]),t._v(" "),e("span",{staticClass:"time"},[t._v(t._s(t.lastUpdated))])]):t._e()])}),[],!1,null,null,null);e.default=c.exports},274:function(t,e,s){"use strict";s.r(e);s(89);var i=s(239),n=s(263),r=s.n(n),a=s(244),o=s.n(a),c={name:"PageNav",props:["sidebarItems"],computed:{prev(){return l(u.PREV,this)},next(){return l(u.NEXT,this)}}};const u={NEXT:{resolveLink:function(t,e){return p(t,e,1)},getThemeLinkConfig:({nextLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.next},PREV:{resolveLink:function(t,e){return p(t,e,-1)},getThemeLinkConfig:({prevLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.prev}};function l(t,{$themeConfig:e,$page:s,$route:n,$site:a,sidebarItems:c}){const{resolveLink:u,getThemeLinkConfig:l,getPageLinkConfig:p}=t,d=l(e),h=p(s),f=o()(h)?d:h;return!1===f?void 0:r()(f)?Object(i.k)(a.pages,f,n.path):u(s,c)}function p(t,e,s){const i=[];!function t(e,s){for(let i=0,n=e.length;i({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}(t);const a=o.sidebar||s.sidebar;if(a){const{base:t,config:n}=function(t,e){if(Array.isArray(e))return{base:"/",config:e};for(const i in e)if(0===(n=t,/(\.html|\/)$/.test(n)?n:n+"/").indexOf(encodeURI(i)))return{base:i,config:e[i]};var n;return{}}(e,a);return n?n.map(e=>function t(e,n,i,r=1){if("string"==typeof e)return h(n,e,i);if(Array.isArray(e))return Object.assign(h(n,e[0],i),{title:e[1]});{r>3&&console.error("[vuepress] detected a too deep nested sidebar group.");const s=e.children||[];return 0===s.length&&e.path?Object.assign(h(n,e.path,i),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,children:s.map(e=>t(e,n,i,r+1)),collapsable:!1!==e.collapsable}}}(e,r,t)):[]}return[]}function m(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function g(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},240:function(t,e,n){},241:function(t,e,n){},249:function(t,e,n){"use strict";n.r(e);var i={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},r=(n(253),n(14)),s=Object(r.a)(i,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=s.exports},250:function(t,e,n){"use strict";n.r(e);var i=n(239),r={props:{item:{required:!0}},computed:{link(){return Object(i.b)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link}},methods:{isExternal:i.f,isMailto:i.g,isTel:i.h,focusoutAction(){this.$emit("focusout")}}},s=(n(252),n(14)),o=Object(s.a)(r,(function(){var t=this,e=t._self._c;return t.isExternal(t.link)?e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.isMailto(t.link)||t.isTel(t.link)?null:"_blank",rel:t.isMailto(t.link)||t.isTel(t.link)?null:"noopener noreferrer"},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),e("OutboundLink")],1):e("router-link",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v(t._s(t.item.text))])}),[],!1,null,"34dbfd23",null);e.default=o.exports},252:function(t,e,n){"use strict";n(240)},253:function(t,e,n){"use strict";n(241)},254:function(t,e,n){},271:function(t,e,n){},276:function(t,e,n){"use strict";n(254)},281:function(t,e,n){"use strict";n.r(e);var i=n(282),r=n(239),s={components:{NavLink:n(250).default,DropdownLink:i.default},computed:{userNav(){return this.$themeLocaleConfig.nav||this.$site.themeConfig.nav||[]},nav(){const{locales:t}=this.$site;if(t&&Object.keys(t).length>1){const e=this.$page.path,n=this.$router.options.routes,i=this.$site.themeConfig.locales||{},r={text:this.$themeLocaleConfig.selectText||"Languages",ariaLabel:this.$themeLocaleConfig.ariaLabel||"Select language",items:Object.keys(t).map(r=>{const s=t[r],o=i[r]&&i[r].label||s.lang;let a;return s.lang===this.$lang?a=e:(a=e.replace(this.$localeConfig.path,r),n.some(t=>t.path===a)||(a=r)),{text:o,link:a}})};return[...this.userNav,r]}return this.userNav},userLinks(){return(this.nav||[]).map(t=>Object.assign(Object(r.j)(t),{items:(t.items||[]).map(r.j)}))},repoLink(){const{repo:t}=this.$site.themeConfig;return t?/^https?:/.test(t)?t:"https://github.com/"+t:null},repoLabel(){if(!this.repoLink)return;if(this.$site.themeConfig.repoLabel)return this.$site.themeConfig.repoLabel;const t=this.repoLink.match(/^https?:\/\/[^/]+/)[0],e=["GitHub","GitLab","Bitbucket"];for(let n=0;n({open:!1}),props:{item:{required:!0}},computed:{dropdownAriaLabel(){return this.item.ariaLabel||this.item.text}},methods:{toggle(){this.open=!this.open},isLastItemOfArray:(t,e)=>o()(e)===t},watch:{$route(){this.open=!1}}},l=(n(276),n(14)),u=Object(l.a)(a,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"dropdown-wrapper",class:{open:t.open}},[e("button",{staticClass:"dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:t.toggle}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow",class:t.open?"down":"right"})]),t._v(" "),e("DropdownTransition",[e("ul",{directives:[{name:"show",rawName:"v-show",value:t.open,expression:"open"}],staticClass:"nav-dropdown"},t._l(t.item.items,(function(n,i){return e("li",{key:n.link||i,staticClass:"dropdown-item"},["links"===n.type?e("div",{staticClass:"dropdown-item-title"},[t._v(t._s(n.text))]):t._e(),t._v(" "),"links"===n.type?e("ul",{staticClass:"dropdown-subitem-wrapper"},t._l(n.items,(function(i){return e("li",{key:i.link,staticClass:"dropdown-subitem"},[e("NavLink",{attrs:{item:i},on:{focusout:function(e){t.isLastItemOfArray(i,n.items)&&t.isLastItemOfArray(n,t.item.items)&&t.toggle()}}})],1)})),0):e("NavLink",{attrs:{item:n},on:{focusout:function(e){t.isLastItemOfArray(n,t.item.items)&&t.toggle()}}})],1)})),0)])],1)}),[],!1,null,null,null);e.default=u.exports},292:function(t,e,n){"use strict";n(271)}}]); \ No newline at end of file diff --git a/assets/js/15.df9825da.js b/assets/js/15.df9825da.js new file mode 100644 index 00000000..26098417 --- /dev/null +++ b/assets/js/15.df9825da.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[15,20,21,24],{239:function(t,e,n){"use strict";n.d(e,"d",(function(){return i})),n.d(e,"a",(function(){return s})),n.d(e,"i",(function(){return o})),n.d(e,"f",(function(){return l})),n.d(e,"g",(function(){return u})),n.d(e,"h",(function(){return c})),n.d(e,"b",(function(){return f})),n.d(e,"e",(function(){return p})),n.d(e,"k",(function(){return d})),n.d(e,"l",(function(){return h})),n.d(e,"c",(function(){return m})),n.d(e,"j",(function(){return g}));n(89);const i=/#.*$/,r=/\.(md|html)$/,s=/\/$/,o=/^[a-z]+:/i;function a(t){return decodeURI(t).replace(i,"").replace(r,"")}function l(t){return o.test(t)}function u(t){return/^mailto:/.test(t)}function c(t){return/^tel:/.test(t)}function f(t){if(l(t))return t;const e=t.match(i),n=e?e[0]:"",r=a(t);return s.test(r)?t:r+".html"+n}function p(t,e){const n=t.hash,r=function(t){const e=t.match(i);if(e)return e[0]}(e);if(r&&n!==r)return!1;return a(t.path)===a(e)}function d(t,e,n){if(l(e))return{type:"external",path:e};n&&(e=function(t,e,n){const i=t.charAt(0);if("/"===i)return t;if("?"===i||"#"===i)return e+t;const r=e.split("/");n&&r[r.length-1]||r.pop();const s=t.replace(/^\//,"").split("/");for(let t=0;t({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}(t);const a=o.sidebar||s.sidebar;if(a){const{base:t,config:n}=function(t,e){if(Array.isArray(e))return{base:"/",config:e};for(const i in e)if(0===(n=t,/(\.html|\/)$/.test(n)?n:n+"/").indexOf(encodeURI(i)))return{base:i,config:e[i]};var n;return{}}(e,a);return n?n.map(e=>function t(e,n,i,r=1){if("string"==typeof e)return d(n,e,i);if(Array.isArray(e))return Object.assign(d(n,e[0],i),{title:e[1]});{r>3&&console.error("[vuepress] detected a too deep nested sidebar group.");const s=e.children||[];return 0===s.length&&e.path?Object.assign(d(n,e.path,i),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,children:s.map(e=>t(e,n,i,r+1)),collapsable:!1!==e.collapsable}}}(e,r,t)):[]}return[]}function m(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function g(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},240:function(t,e,n){},241:function(t,e,n){},249:function(t,e,n){"use strict";n.r(e);var i={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},r=(n(253),n(14)),s=Object(r.a)(i,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=s.exports},250:function(t,e,n){"use strict";n.r(e);var i=n(239),r={props:{item:{required:!0}},computed:{link(){return Object(i.b)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link}},methods:{isExternal:i.f,isMailto:i.g,isTel:i.h,focusoutAction(){this.$emit("focusout")}}},s=(n(252),n(14)),o=Object(s.a)(r,(function(){var t=this,e=t._self._c;return t.isExternal(t.link)?e("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.isMailto(t.link)||t.isTel(t.link)?null:"_blank",rel:t.isMailto(t.link)||t.isTel(t.link)?null:"noopener noreferrer"},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),e("OutboundLink")],1):e("router-link",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(e){return t.focusoutAction.apply(null,arguments)}}},[t._v(t._s(t.item.text))])}),[],!1,null,"34dbfd23",null);e.default=o.exports},252:function(t,e,n){"use strict";n(240)},253:function(t,e,n){"use strict";n(241)},254:function(t,e,n){},276:function(t,e,n){"use strict";n(254)},282:function(t,e,n){"use strict";n.r(e);var i=n(250),r=n(249),s=n(92),o=n.n(s),a={components:{NavLink:i.default,DropdownTransition:r.default},data:()=>({open:!1}),props:{item:{required:!0}},computed:{dropdownAriaLabel(){return this.item.ariaLabel||this.item.text}},methods:{toggle(){this.open=!this.open},isLastItemOfArray:(t,e)=>o()(e)===t},watch:{$route(){this.open=!1}}},l=(n(276),n(14)),u=Object(l.a)(a,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"dropdown-wrapper",class:{open:t.open}},[e("button",{staticClass:"dropdown-title",attrs:{type:"button","aria-label":t.dropdownAriaLabel},on:{click:t.toggle}},[e("span",{staticClass:"title"},[t._v(t._s(t.item.text))]),t._v(" "),e("span",{staticClass:"arrow",class:t.open?"down":"right"})]),t._v(" "),e("DropdownTransition",[e("ul",{directives:[{name:"show",rawName:"v-show",value:t.open,expression:"open"}],staticClass:"nav-dropdown"},t._l(t.item.items,(function(n,i){return e("li",{key:n.link||i,staticClass:"dropdown-item"},["links"===n.type?e("div",{staticClass:"dropdown-item-title"},[t._v(t._s(n.text))]):t._e(),t._v(" "),"links"===n.type?e("ul",{staticClass:"dropdown-subitem-wrapper"},t._l(n.items,(function(i){return e("li",{key:i.link,staticClass:"dropdown-subitem"},[e("NavLink",{attrs:{item:i},on:{focusout:function(e){t.isLastItemOfArray(i,n.items)&&t.isLastItemOfArray(n,t.item.items)&&t.toggle()}}})],1)})),0):e("NavLink",{attrs:{item:n},on:{focusout:function(e){t.isLastItemOfArray(n,t.item.items)&&t.toggle()}}})],1)})),0)])],1)}),[],!1,null,null,null);e.default=u.exports}}]); \ No newline at end of file diff --git a/assets/js/16.25cbe1cc.js b/assets/js/16.25cbe1cc.js new file mode 100644 index 00000000..a7d65208 --- /dev/null +++ b/assets/js/16.25cbe1cc.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[16],{286:function(e,t,a){"use strict";var i=TypeError;e.exports=function(e,t){if(e({placeholder:void 0}),mounted(){this.initialize(this.options,this.$lang),this.placeholder=this.$site.themeConfig.searchPlaceholder||""},methods:{initialize(e,t){Promise.all([Promise.all([a.e(0),a.e(11)]).then(a.t.bind(null,324,7)),Promise.all([a.e(0),a.e(11)]).then(a.t.bind(null,325,7))]).then(([a])=>{a=a.default;const{algoliaOptions:i={}}=e;a(Object.assign({},e,{inputSelector:"#algolia-search-input",algoliaOptions:Object.assign({facetFilters:["lang:"+t].concat(i.facetFilters||[])},i),handleSelected:(e,t,a)=>{const{pathname:i,hash:n}=new URL(a.url);this.$router.push(`${i}${n}`)}}))})},update(e,t){this.$el.innerHTML='',this.initialize(e,t)}},watch:{$lang(e){this.update(this.options,e)},options(e){this.update(e,this.$lang)}}},n=(a(298),a(14)),r=Object(n.a)(i,(function(){var e=this._self._c;return e("form",{staticClass:"algolia-search-wrapper search-box",attrs:{id:"search-form",role:"search"}},[e("input",{staticClass:"search-query",attrs:{id:"algolia-search-input",placeholder:this.placeholder}})])}),[],!1,null,null,null);t.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/17.4f8def75.js b/assets/js/17.4f8def75.js new file mode 100644 index 00000000..df8e09ec --- /dev/null +++ b/assets/js/17.4f8def75.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[17],{239:function(t,e,n){"use strict";n.d(e,"d",(function(){return r})),n.d(e,"a",(function(){return o})),n.d(e,"i",(function(){return s})),n.d(e,"f",(function(){return a})),n.d(e,"g",(function(){return c})),n.d(e,"h",(function(){return p})),n.d(e,"b",(function(){return l})),n.d(e,"e",(function(){return f})),n.d(e,"k",(function(){return h})),n.d(e,"l",(function(){return d})),n.d(e,"c",(function(){return g})),n.d(e,"j",(function(){return v}));n(89);const r=/#.*$/,i=/\.(md|html)$/,o=/\/$/,s=/^[a-z]+:/i;function u(t){return decodeURI(t).replace(r,"").replace(i,"")}function a(t){return s.test(t)}function c(t){return/^mailto:/.test(t)}function p(t){return/^tel:/.test(t)}function l(t){if(a(t))return t;const e=t.match(r),n=e?e[0]:"",i=u(t);return o.test(i)?t:i+".html"+n}function f(t,e){const n=t.hash,i=function(t){const e=t.match(r);if(e)return e[0]}(e);if(i&&n!==i)return!1;return u(t.path)===u(e)}function h(t,e,n){if(a(e))return{type:"external",path:e};n&&(e=function(t,e,n){const r=t.charAt(0);if("/"===r)return t;if("?"===r||"#"===r)return e+t;const i=e.split("/");n&&i[i.length-1]||i.pop();const o=t.replace(/^\//,"").split("/");for(let t=0;t({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}(t);const u=s.sidebar||o.sidebar;if(u){const{base:t,config:n}=function(t,e){if(Array.isArray(e))return{base:"/",config:e};for(const r in e)if(0===(n=t,/(\.html|\/)$/.test(n)?n:n+"/").indexOf(encodeURI(r)))return{base:r,config:e[r]};var n;return{}}(e,u);return n?n.map(e=>function t(e,n,r,i=1){if("string"==typeof e)return h(n,e,r);if(Array.isArray(e))return Object.assign(h(n,e[0],r),{title:e[1]});{i>3&&console.error("[vuepress] detected a too deep nested sidebar group.");const o=e.children||[];return 0===o.length&&e.path?Object.assign(h(n,e.path,r),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,children:o.map(e=>t(e,n,r,i+1)),collapsable:!1!==e.collapsable}}}(e,i,t)):[]}return[]}function g(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function v(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},244:function(t,e){t.exports=function(t){return null==t}},246:function(t,e,n){},263:function(t,e,n){var r=n(11),i=n(4),o=n(10);t.exports=function(t){return"string"==typeof t||!i(t)&&o(t)&&"[object String]"==r(t)}},264:function(t,e,n){"use strict";n(246)},274:function(t,e,n){"use strict";n.r(e);n(89);var r=n(239),i=n(263),o=n.n(i),s=n(244),u=n.n(s),a={name:"PageNav",props:["sidebarItems"],computed:{prev(){return p(c.PREV,this)},next(){return p(c.NEXT,this)}}};const c={NEXT:{resolveLink:function(t,e){return l(t,e,1)},getThemeLinkConfig:({nextLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.next},PREV:{resolveLink:function(t,e){return l(t,e,-1)},getThemeLinkConfig:({prevLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.prev}};function p(t,{$themeConfig:e,$page:n,$route:i,$site:s,sidebarItems:a}){const{resolveLink:c,getThemeLinkConfig:p,getPageLinkConfig:l}=t,f=p(e),h=l(n),d=u()(h)?f:h;return!1===d?void 0:o()(d)?Object(r.k)(s.pages,d,i.path):c(n,a)}function l(t,e,n){const r=[];!function t(e,n){for(let r=0,i=e.length;r({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}(t);const u=s.sidebar||a.sidebar;if(u){const{base:t,config:n}=function(t,e){if(Array.isArray(e))return{base:"/",config:e};for(const r in e)if(0===(n=t,/(\.html|\/)$/.test(n)?n:n+"/").indexOf(encodeURI(r)))return{base:r,config:e[r]};var n;return{}}(e,u);return n?n.map(e=>function t(e,n,r,i=1){if("string"==typeof e)return d(n,e,r);if(Array.isArray(e))return Object.assign(d(n,e[0],r),{title:e[1]});{i>3&&console.error("[vuepress] detected a too deep nested sidebar group.");const a=e.children||[];return 0===a.length&&e.path?Object.assign(d(n,e.path,r),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,children:a.map(e=>t(e,n,r,i+1)),collapsable:!1!==e.collapsable}}}(e,i,t)):[]}return[]}function b(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function g(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},242:function(t,e,n){},243:function(t,e,n){},256:function(t,e,n){"use strict";n(242)},257:function(t,e,n){"use strict";n(243)},261:function(t,e,n){"use strict";n.r(e);var r=n(239);function i(t,e,n,r){return t("router-link",{props:{to:e,activeClass:"",exactActiveClass:""},class:{active:r,"sidebar-link":!0}},n)}function a(t,e,n,s,u,o=1){return!e||o>u?null:t("ul",{class:"sidebar-sub-headers"},e.map(e=>{const c=Object(r.e)(s,n+"#"+e.slug);return t("li",{class:"sidebar-sub-header"},[i(t,n+"#"+e.slug,e.title,c),a(t,e.children,n,s,u,o+1)])}))}var s={functional:!0,props:["item","sidebarDepth"],render(t,{parent:{$page:e,$site:n,$route:s,$themeConfig:u,$themeLocaleConfig:o},props:{item:c,sidebarDepth:l}}){const p=Object(r.e)(s,c.path),f="auto"===c.type?p||c.children.some(t=>Object(r.e)(s,c.basePath+"#"+t.slug)):p,d="external"===c.type?function(t,e,n){return t("a",{attrs:{href:e,target:"_blank",rel:"noopener noreferrer"},class:{"sidebar-link":!0}},[n,t("OutboundLink")])}(t,c.path,c.title||c.path):i(t,c.path,c.title||c.path,f),h=[e.frontmatter.sidebarDepth,l,o.sidebarDepth,u.sidebarDepth,1].find(t=>void 0!==t),b=o.displayAllHeaders||u.displayAllHeaders;if("auto"===c.type)return[d,a(t,c.children,c.basePath,s,h)];if((f||b)&&c.headers&&!r.d.test(c.path)){return[d,a(t,Object(r.c)(c.headers),c.path,s,h)]}return d}},u=(n(256),n(257),n(14)),o=Object(u.a)(s,void 0,void 0,!1,null,"a68ca4e6",null);e.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/19.76e3b2e8.js b/assets/js/19.76e3b2e8.js new file mode 100644 index 00000000..7dcbdaf7 --- /dev/null +++ b/assets/js/19.76e3b2e8.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[19],{239:function(t,e,n){"use strict";n.d(e,"d",(function(){return i})),n.d(e,"a",(function(){return s})),n.d(e,"i",(function(){return a})),n.d(e,"f",(function(){return c})),n.d(e,"g",(function(){return u})),n.d(e,"h",(function(){return l})),n.d(e,"b",(function(){return d})),n.d(e,"e",(function(){return p})),n.d(e,"k",(function(){return f})),n.d(e,"l",(function(){return h})),n.d(e,"c",(function(){return g})),n.d(e,"j",(function(){return m}));n(89);const i=/#.*$/,r=/\.(md|html)$/,s=/\/$/,a=/^[a-z]+:/i;function o(t){return decodeURI(t).replace(i,"").replace(r,"")}function c(t){return a.test(t)}function u(t){return/^mailto:/.test(t)}function l(t){return/^tel:/.test(t)}function d(t){if(c(t))return t;const e=t.match(i),n=e?e[0]:"",r=o(t);return s.test(r)?t:r+".html"+n}function p(t,e){const n=t.hash,r=function(t){const e=t.match(i);if(e)return e[0]}(e);if(r&&n!==r)return!1;return o(t.path)===o(e)}function f(t,e,n){if(c(e))return{type:"external",path:e};n&&(e=function(t,e,n){const i=t.charAt(0);if("/"===i)return t;if("?"===i||"#"===i)return e+t;const r=e.split("/");n&&r[r.length-1]||r.pop();const s=t.replace(/^\//,"").split("/");for(let t=0;t({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}(t);const o=a.sidebar||s.sidebar;if(o){const{base:t,config:n}=function(t,e){if(Array.isArray(e))return{base:"/",config:e};for(const i in e)if(0===(n=t,/(\.html|\/)$/.test(n)?n:n+"/").indexOf(encodeURI(i)))return{base:i,config:e[i]};var n;return{}}(e,o);return n?n.map(e=>function t(e,n,i,r=1){if("string"==typeof e)return f(n,e,i);if(Array.isArray(e))return Object.assign(f(n,e[0],i),{title:e[1]});{r>3&&console.error("[vuepress] detected a too deep nested sidebar group.");const s=e.children||[];return 0===s.length&&e.path?Object.assign(f(n,e.path,i),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,children:s.map(e=>t(e,n,i,r+1)),collapsable:!1!==e.collapsable}}}(e,r,t)):[]}return[]}function g(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function m(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},244:function(t,e){t.exports=function(t){return null==t}},245:function(t,e,n){},262:function(t,e,n){"use strict";n(245)},273:function(t,e,n){"use strict";n.r(e);var i=n(244),r=n.n(i),s=n(239),a={name:"PageEdit",computed:{lastUpdated(){return this.$page.lastUpdated},lastUpdatedText(){return"string"==typeof this.$themeLocaleConfig.lastUpdated?this.$themeLocaleConfig.lastUpdated:"string"==typeof this.$site.themeConfig.lastUpdated?this.$site.themeConfig.lastUpdated:"Last Updated"},editLink(){const t=r()(this.$page.frontmatter.editLink)?this.$site.themeConfig.editLinks:this.$page.frontmatter.editLink,{repo:e,docsDir:n="",docsBranch:i="master",docsRepo:s=e}=this.$site.themeConfig;return t&&s&&this.$page.relativePath?this.createEditLink(e,s,n,i,this.$page.relativePath):null},editLinkText(){return this.$themeLocaleConfig.editLinkText||this.$site.themeConfig.editLinkText||"Edit this page"}},methods:{createEditLink(t,e,n,i,r){if(/bitbucket.org/.test(t)){return(s.i.test(e)?e:t).replace(s.a,"")+"/src"+`/${i}/`+(n?n.replace(s.a,"")+"/":"")+r+`?mode=edit&spa=0&at=${i}&fileviewer=file-view-default`}return(s.i.test(e)?e:"https://github.com/"+e).replace(s.a,"")+"/edit"+`/${i}/`+(n?n.replace(s.a,"")+"/":"")+r}}},o=(n(262),n(14)),c=Object(o.a)(a,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"page-edit"},[t.editLink?e("div",{staticClass:"edit-link"},[e("a",{attrs:{href:t.editLink,target:"_blank",rel:"noopener noreferrer"}},[t._v(t._s(t.editLinkText))]),t._v(" "),e("OutboundLink")],1):t._e(),t._v(" "),t.lastUpdated?e("div",{staticClass:"last-updated"},[e("span",{staticClass:"prefix"},[t._v(t._s(t.lastUpdatedText)+":")]),t._v(" "),e("span",{staticClass:"time"},[t._v(t._s(t.lastUpdated))])]):t._e()])}),[],!1,null,null,null);e.default=c.exports}}]); \ No newline at end of file diff --git a/assets/js/2.89a92fa3.js b/assets/js/2.89a92fa3.js new file mode 100644 index 00000000..4d345723 --- /dev/null +++ b/assets/js/2.89a92fa3.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[2,22,23,25,28],{269:function(t,e,s){},270:function(t,e,s){},272:function(t,e,s){"use strict";s.r(e);var a={data:()=>({year:(new Date).getFullYear()})},i=(s(290),s(14)),r=Object(i.a)(a,(function(){var t=this,e=t._self._c;return e("footer",[e("section",[e("div",{staticClass:"col"},[e("h4",[t._v("Docs")]),t._v(" "),e("ul",[e("li",[e("router-link",{attrs:{to:"/quickstart"}},[t._v("Quickstart")])],1),t._v(" "),e("li",[e("router-link",{attrs:{to:"/basics"}},[t._v("Getting Started")])],1),t._v(" "),e("li",[e("router-link",{attrs:{to:"/playwright"}},[t._v("CodeceptJS & Playwright")])],1),t._v(" "),e("li",[e("router-link",{attrs:{to:"/puppeteer"}},[t._v("CodeceptJS & WebDriver")])],1)])]),t._v(" "),t._m(0),t._v(" "),t._m(1),t._v(" "),t._m(2)]),t._v(" "),e("div",{staticClass:"copyright"},[e("h5",[t._v("CodeceptJS - supercharged end 2 end testing framework for NodeJS")]),t._v("\n © "+t._s(t.year)+"\n ")])])}),[function(){var t=this,e=t._self._c;return e("div",{staticClass:"col"},[e("h4",[t._v("Community")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS"}},[t._v("GitHub")])]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/discussions"}},[t._v("GitHub discussions")])]),t._v(" "),e("li",[e("a",{attrs:{href:"https://bit.ly/chat-codeceptjs"}},[t._v("Slack Chat")])]),t._v(" "),e("li",[e("a",{attrs:{href:"https://codecept.discourse.group/"}},[t._v("Forum")])]),t._v(" "),e("li",[e("a",{attrs:{href:"https://twitter.com/codeceptjs"}},[t._v("Twitter")])])])])},function(){var t=this._self._c;return t("div",{staticClass:"col"},[t("h4",{staticClass:"important"},[this._v("Commercial Support")]),this._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://sdclabs.com/codeceptjs?utm_source=codecept.io&utm_medium=footer&utm_term=link&utm_campaign=reference"}},[this._v("Consulting")])]),this._v(" "),t("li",[t("a",{attrs:{href:"https://sdclabs.com/trainings/web-automation-codeceptjs?utm_source=codecept.io&utm_medium=top_menu&utm_term=link&utm_campaign=reference"}},[this._v("Trainings")])]),this._v(" "),t("li",[t("a",{attrs:{href:"https://sdclabs.com/#services"}},[this._v("Hire Engineers")])])])])},function(){var t=this._self._c;return t("div",{staticClass:"col"},[t("a",{attrs:{href:"https://testomat.io"}},[t("h4",[this._v("Try Testomat.io →")]),this._v(" "),t("p",[this._v("Powerful "),t("b",[this._v("Test Case Management")]),this._v(" for CodeceptJS from its authors")])])])}],!1,null,"5616cc4e",null);e.default=r.exports},275:function(t,e,s){"use strict";s.r(e);s(288);var a=s(14),i=Object(a.a)({},(function(){this._self._c;return this._m(0)}),[function(){var t=this._self._c;return t("div",{staticClass:"banner"},[t("a",{attrs:{href:"https://opencollective.com/codeceptjs"}},[this._v("CodeceptJS is on OpenCollective! Support us 💖")])])}],!1,null,"436508ca",null);e.default=i.exports},288:function(t,e,s){"use strict";s(269)},289:function(t,e,s){},290:function(t,e,s){"use strict";s(270)},291:function(t,e,s){},299:function(t,e,s){"use strict";s(289)},300:function(t,e,s){"use strict";s(291)},303:function(t,e,s){"use strict";s.r(e);var a=s(250),i=s(314),r=s(313),n=s(272),o=s(275),l={components:{NavLink:a.default,Footer:n.default,Slides:i.default,Companies:r.default,Banner:o.default},data:()=>({showVideo:!1}),methods:{toggleVideo(t){t.preventDefault(),this.showVideo=!this.showVideo;const e=()=>{this.showVideo=!1,document.body.removeEventListener("click",e)};return setTimeout(()=>document.body.addEventListener("click",e),0),!1},hideVideo(){this.showVideo=!1}},computed:{data(){return this.$page.frontmatter},actionLink(){return{link:this.data.actionLink,text:this.data.actionText}}}},c=(s(316),s(317),s(14)),d=Object(c.a)(l,(function(){var t=this,e=t._self._c;return e("main",{staticClass:"home"},[e("div",{staticClass:"hero"},[e("div",{staticClass:"mountains"},[t.data.heroImage?e("img",{attrs:{src:t.$withBase(t.data.heroImage),alt:t.data.heroAlt||"hero"}}):t._e(),t._v(" "),t._m(0),t._v(" "),t._m(1),t._v(" "),e("img",{staticClass:"ui",attrs:{src:"/img/runui.gif",alt:"CodeceptUI"}}),t._v(" "),t.data.actionText&&t.data.actionLink?e("p",{staticClass:"action"},[e("NavLink",{staticClass:"action-button",attrs:{item:t.actionLink}})],1):t._e()])]),t._v(" "),e("div",{staticClass:"frameworks"},[e("div",{staticClass:"content"},[e("b",[t._v("CodeceptJS")]),t._v(" is opensource MIT licensed testing framework.\n "),e("h4",[t._v("\n Works with your favorite frontend frameworks →\n "),e("router-link",{attrs:{to:"/react"}},[e("img",{attrs:{src:"/img/react.svg",alt:"React"}})]),t._v(" "),e("router-link",{attrs:{to:"/vue"}},[e("img",{attrs:{src:"/img/vue.svg",alt:"Vue"}})]),t._v(" "),e("router-link",{attrs:{to:"/angular"}},[e("img",{attrs:{src:"/img/AngularLogo.png",alt:"Angular"}})])],1)])]),t._v(" "),e("div",{staticClass:"content"},[e("div",{staticClass:"features"},[t._m(2),t._v(" "),e("div",{staticClass:"feature"},[e("img",{attrs:{src:"/img/Mind-Map-Paper.svg",alt:"Mind map paper"}}),t._v(" "),e("div",{staticClass:"inner"},[e("h5",[t._v("Driver Agnostic")]),t._v("\n Run your tests via "),e("b",[t._v("Playwright, WebDriver, Puppeteer, TestCafe, Protractor, Appium")]),t._v(". The code is the same.\n "),e("router-link",{attrs:{to:"/basics#architecture"}},[t._v("Learn More")])],1)]),t._v(" "),e("div",{staticClass:"feature"},[e("img",{attrs:{src:"/img/Coding-Html.svg",alt:"Html coding"}}),t._v(" "),e("div",{staticClass:"inner"},[e("h5",[t._v("Interactive Debug")]),t._v("\n Control tests as they run. Pause tests at any point and execute commands to try locators.\n "),e("router-link",{attrs:{to:"/basics#debug"}},[t._v("Learn More")])],1)])]),t._v(" "),e("div",{staticClass:"features"},[e("div",{staticClass:"feature"},[e("img",{attrs:{src:"/img/Prism-3.svg",alt:"feature"}}),t._v(" "),e("div",{staticClass:"inner"},[e("h5",[t._v("Rich Locators")]),t._v("\n Use semantic locators, CSS, XPath to find elements on page\n "),e("router-link",{attrs:{to:"/locators"}},[t._v("Learn More")])],1)]),t._v(" "),e("div",{staticClass:"feature"},[e("img",{staticStyle:{filter:"hue-rotate(45deg)",transform:"rotate(225deg)"},attrs:{src:"/img/Prism-3.svg",alt:"feature"}}),t._v(" "),e("div",{staticClass:"inner"},[e("h5",[t._v("PageObjects")]),t._v("\n PageObjects are essential to write stable and reusable code!\n "),e("router-link",{attrs:{to:"/pageobjects"}},[t._v("Learn More")])],1)]),t._v(" "),e("div",{staticClass:"feature"},[e("img",{staticStyle:{filter:"hue-rotate(90deg)",transform:"rotate(180deg)"},attrs:{src:"/img/Prism-3.svg",alt:"feature"}}),t._v(" "),e("div",{staticClass:"inner"},[e("h5",[t._v("Web & Mobile Testing")]),t._v("\n Test native mobile apps using "),e("b",[t._v("Appium")]),t._v(" or "),e("b",[t._v("Detox")]),t._v(".\n "),e("router-link",{attrs:{to:"/mobile"}},[t._v("Learn More")])],1)])]),t._v(" "),e("div",{staticClass:"features"},[e("div",{staticClass:"feature"},[e("img",{staticStyle:{filter:"hue-rotate(135deg)",transform:"rotate(45deg)"},attrs:{src:"/img/Prism-3.svg",alt:"feature"}}),t._v(" "),e("div",{staticClass:"inner"},[e("h5",[t._v("Cucumber-like BDD")]),t._v("\n Automate business scenarios as you do in CucumberJS\n "),e("router-link",{attrs:{to:"/bdd"}},[t._v("Learn More")])],1)]),t._v(" "),e("div",{staticClass:"feature"},[e("img",{staticStyle:{filter:"hue-rotate(180deg)",transform:"rotate(90deg)"},attrs:{src:"/img/Prism-3.svg",alt:"feature"}}),t._v(" "),e("div",{staticClass:"inner"},[e("h5",[t._v("API Testing")]),t._v("\n Write tests for "),e("b",[t._v("REST")]),t._v(" and "),e("b",[t._v("GraphQL")]),t._v(" APIs \n "),e("router-link",{attrs:{to:"/api"}},[t._v("Learn More ")])],1)]),t._v(" "),e("div",{staticClass:"feature"},[e("img",{staticStyle:{filter:"hue-rotate(225deg)",transform:"rotate(135deg)"},attrs:{src:"/img/Prism-3.svg",alt:"feature"}}),t._v(" "),e("div",{staticClass:"inner"},[e("h5",[t._v("Data Management")]),t._v("\n Create fake data and clean it up via REST API\n "),e("router-link",{attrs:{to:"/data"}},[t._v("Learn More ")])],1)])]),t._v(" "),e("div",{staticClass:"features"},[e("div",{staticClass:"feature"},[e("img",{staticStyle:{transform:"rotate(90deg)",filter:"hue-rotate(60deg) saturate(20%)"},attrs:{src:"/img/Prism-3.svg",alt:"feature"}}),t._v(" "),e("div",{staticClass:"inner"},[e("h5",[t._v("Parallel Testing")]),t._v("\n Tests are split into chunks and executed in multiple processes.\n "),e("router-link",{attrs:{to:"/advanced#parallel-execution"}},[t._v("Learn More ")])],1)]),t._v(" "),e("div",{staticClass:"feature"},[e("img",{staticStyle:{filter:"hue-rotate(105deg) saturate(20%)",transform:"rotate(45deg)"},attrs:{src:"/img/Prism-3.svg",alt:"feature"}}),t._v(" "),e("div",{staticClass:"inner"},[e("h5",[t._v("Reduced Flackiness")]),t._v("\n Automatically retry failed steps\n "),e("router-link",{attrs:{to:"/basics#retries"}},[t._v("Learn More ")])],1)]),t._v(" "),e("div",{staticClass:"feature"},[e("img",{staticStyle:{filter:"hue-rotate(135deg) saturate(20%)",transform:"rotate(0deg)"},attrs:{src:"/img/Prism-3.svg",alt:"feature"}}),t._v(" "),e("div",{staticClass:"inner"},[e("h5",[t._v("AI-powered")]),t._v("\n Use OpenAI GPT to heal failing tests\n "),e("router-link",{attrs:{to:"/ai"}},[t._v("Learn More ")])],1)])])]),t._v(" "),e("div",{staticClass:"demos"},[e("ClientOnly",[e("Slides")],1)],1),t._v(" "),e("div",{staticClass:"content"},[e("Content",{attrs:{"slot-key":"code"}})],1),t._v(" "),e("section",{staticClass:"testimonials"},[e("div",{staticClass:"inner"},[e("h2",{staticClass:"text-center"},[t._v("Trusted By Enterprises")]),t._v(" "),e("div",{staticClass:"companies"},[e("ClientOnly",[e("Companies")],1)],1),t._v(" "),e("h2",{staticClass:"text-center"},[t._v("Loved By Teams")]),t._v(" "),t._m(3)])]),t._v(" "),t._m(4),t._v(" "),e("Footer")],1)}),[function(){var t=this._self._c;return t("h1",[t("span",{staticClass:"name"},[this._v("CodeceptJS")]),this._v(" ‐ supercharged"),t("br"),t("span",{staticClass:"name"},[this._v("End 2 End")]),this._v(" Testing\n ")])},function(){var t=this._self._c;return t("div",{staticClass:"ai"},[this._v("First \n "),t("a",{attrs:{href:"/ai"}},[this._v("AI-powered")]),this._v("\n testing framework 🪄 ")])},function(){var t=this._self._c;return t("div",{staticClass:"feature"},[t("img",{attrs:{src:"/img/Checklist.svg",alt:"checklist"}}),this._v(" "),t("div",{staticClass:"inner"},[t("h5",[this._v("Scenario Driven")]),this._v("\n Write acceptance tests from user's perspective.\n Make tests readable and easy to follow.\n ")])])},function(){var t=this,e=t._self._c;return e("div",{staticClass:"row"},[e("div",{staticClass:"quote"},[e("p",[t._v("\n We have been using CodeceptJS as our UI testing framework, and it has made writing tests so simp le for us, the amount of options and features available in CodeceptJS just out of the box are perfect for us to "),e("b",[t._v("test an application like Percona Monitoring and Management")]),t._v(" (PMM), with so many dashboards & Metric plots.\n We would recommend CodeceptJS to anyone who is looking for a Javascript based testing framework.\n ")]),t._v(" "),e("div",{staticClass:"signature"},[e("img",{attrs:{src:"/img/kala.jpg",alt:"kala"}}),t._v(" "),e("div",{staticClass:"position"},[e("b",[t._v("Puneet Kala")]),e("br"),t._v(" Frontend QA Automation Engineer at "),e("b",[t._v("Percona")])])])]),t._v(" "),e("div",{staticClass:"quote"},[e("p",[t._v("\n We were searching for a solution to write tests which are good to read and easy to write. It must be able to run on several browsers and understandable across different teams with different knowledge and different frameworks in usage. "),e("b",[t._v("CodeceptJS helps us with all this and much more at Porsche")]),t._v(" and we are happy that we made that decision.\n ")]),t._v(" "),e("div",{staticClass:"signature"},[e("img",{attrs:{src:"/img/mitko.jpg",alt:"mitko"}}),t._v(" "),e("div",{staticClass:"position"},[e("b",[t._v("Mitko Tschimev")]),e("br"),t._v(" Frontend Tech Lead at "),e("b",[t._v("My Porsche Core")])])])])])},function(){var t=this._self._c;return t("section",{staticClass:"testomatio"},[this._v("\n 🚀 Get more of CodeceptJS"),t("br"),this._v(" "),t("a",{attrs:{href:"https://testomat.io"}},[this._v("\n ✅ Try Testomat.io, next-gen "),t("b",[this._v("Test Management")]),this._v(" system for automated & manual tests. ")]),t("br"),this._v("Brought to you by creators of CodeceptJS.\n ")])}],!1,null,"e3b729f8",null);e.default=d.exports},304:function(t,e,s){},305:function(t,e,s){},313:function(t,e,s){"use strict";s.r(e);var a={data:()=>({slideComp:null,carouselComp:null,nextLabel:"",prevLabel:""}),mounted(){s.e(9).then(s.t.bind(null,326,7)).then(t=>{this.slideComp=t.Slide,this.carouselComp=t.Carousel})}},i=(s(299),s(14)),r=Object(i.a)(a,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"slider"},[t.carouselComp?e(t.carouselComp,{tag:"carousel",attrs:{navigationEnabled:!0,autoplayTimeout:1e4,autoplay:!1,"per-page":1,"navigation-next-label":t.nextLabel,"navigation-prev-label":t.prevLabel,"center-mode":!0,perPageCustom:[[768,2],[1024,3]]}},[e(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[e("div",{staticClass:"slide"},[e("img",{attrs:{src:"/img/companies/doxyme.png",title:"Doxy.me",alt:"Doxy.me"}})])]),t._v(" "),e(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[e("div",{staticClass:"slide"},[e("img",{staticClass:"rounded",attrs:{src:"/img/companies/zenitech.png",title:"Zenitech",alt:"Zenitech"}})])]),t._v(" "),e(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[e("div",{staticClass:"slide"},[e("img",{staticClass:"rounded",staticStyle:{"max-height":"95px"},attrs:{src:"/img/companies/kiabi.png",title:"Kiabi",alt:"Kiabi"}})])]),t._v(" "),e(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[e("div",{staticClass:"slide"},[e("img",{staticClass:"rounded mynd-img",staticStyle:{"max-height":"65px"},attrs:{src:"/img/companies/mynd.png",title:"Mynd",alt:"Mynd"}})])]),t._v(" "),e(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[e("div",{staticClass:"slide"},[e("img",{staticClass:"rounded",staticStyle:{background:"rgb(143 156 150)",padding:"10px","max-height":"75px"},attrs:{src:"/img/companies/gen3.png",title:"Gen3",alt:"Gen3"}})])]),t._v(" "),e(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[e("div",{staticClass:"slide"},[e("img",{staticClass:"rounded",attrs:{src:"/img/companies/isotipo.png",title:"Gamelearn",alt:"Gamelearn"}})])]),t._v(" "),e(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[e("div",{staticClass:"slide"},[e("img",{staticClass:"rounded",attrs:{src:"/img/companies/BC_LogoScreen_C.jpg",title:"Betclick",alt:"Betclick"}})])])],1):t._e()],1)}),[],!1,null,"59131a2e",null);e.default=r.exports},314:function(t,e,s){"use strict";s.r(e);var a={data:()=>({slideComp:null,carouselComp:null,nextLabel:"",prevLabel:""}),mounted(){s.e(9).then(s.t.bind(null,326,7)).then(t=>{this.slideComp=t.Slide,this.carouselComp=t.Carousel})}},i=(s(300),s(14)),r=Object(i.a)(a,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"slider"},[t.carouselComp?e(t.carouselComp,{tag:"carousel",attrs:{navigationEnabled:!0,autoplayTimeout:1e4,autoplay:!0,"per-page":1,"navigation-next-label":t.nextLabel,"navigation-prev-label":t.prevLabel,"center-mode":!0}},[e(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[e("div",{staticClass:"slide"},[e("img",{attrs:{src:"/img/pause.gif",alt:"pause"}}),t._v(" "),e("div",[e("Content",{attrs:{"slot-key":"pause"}})],1)])]),t._v(" "),e(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[e("div",{staticClass:"slide"},[e("img",{attrs:{src:"/img/test.gif",alt:"test"}}),t._v(" "),e("div",[e("Content",{attrs:{"slot-key":"run"}})],1)])]),t._v(" "),e(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[e("div",{staticClass:"slide"},[e("img",{attrs:{src:"/img/edit.gif",alt:"edit"}}),t._v(" "),e("div",[e("Content",{attrs:{"slot-key":"autocomplete"}})],1)])]),t._v(" "),e(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[e("div",{staticClass:"slide"},[e("img",{attrs:{src:"/img/codeceptui.gif",alt:"codeceptui"}}),t._v(" "),e("div",[e("Content",{attrs:{"slot-key":"ui"}}),t._v(" "),e("router-link",{staticClass:"button green",attrs:{to:"ui"}},[t._v("Try CodeceptUI →")])],1)])]),t._v(" "),e(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[e("div",{staticClass:"slide"},[e("img",{attrs:{src:"/img/new-test.gif",alt:"new-test"}}),t._v(" "),e("div",[e("Content",{attrs:{"slot-key":"write"}}),t._v(" "),e("router-link",{staticClass:"button green",attrs:{to:"ui"}},[t._v("Try CodeceptUI →")])],1)])])],1):t._e()],1)}),[],!1,null,null,null);e.default=r.exports},316:function(t,e,s){"use strict";s(304)},317:function(t,e,s){"use strict";s(305)}}]); \ No newline at end of file diff --git a/assets/js/20.e54653ad.js b/assets/js/20.e54653ad.js new file mode 100644 index 00000000..5692fc45 --- /dev/null +++ b/assets/js/20.e54653ad.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[20,21],{239:function(t,n,e){"use strict";e.d(n,"d",(function(){return r})),e.d(n,"a",(function(){return o})),e.d(n,"i",(function(){return s})),e.d(n,"f",(function(){return c})),e.d(n,"g",(function(){return l})),e.d(n,"h",(function(){return a})),e.d(n,"b",(function(){return f})),e.d(n,"e",(function(){return p})),e.d(n,"k",(function(){return h})),e.d(n,"l",(function(){return d})),e.d(n,"c",(function(){return b})),e.d(n,"j",(function(){return g}));e(89);const r=/#.*$/,i=/\.(md|html)$/,o=/\/$/,s=/^[a-z]+:/i;function u(t){return decodeURI(t).replace(r,"").replace(i,"")}function c(t){return s.test(t)}function l(t){return/^mailto:/.test(t)}function a(t){return/^tel:/.test(t)}function f(t){if(c(t))return t;const n=t.match(r),e=n?n[0]:"",i=u(t);return o.test(i)?t:i+".html"+e}function p(t,n){const e=t.hash,i=function(t){const n=t.match(r);if(n)return n[0]}(n);if(i&&e!==i)return!1;return u(t.path)===u(n)}function h(t,n,e){if(c(n))return{type:"external",path:n};e&&(n=function(t,n,e){const r=t.charAt(0);if("/"===r)return t;if("?"===r||"#"===r)return n+t;const i=n.split("/");e&&i[i.length-1]||i.pop();const o=t.replace(/^\//,"").split("/");for(let t=0;t({type:"auto",title:n.title,basePath:t.path,path:t.path+"#"+n.slug,children:n.children||[]}))}]}(t);const u=s.sidebar||o.sidebar;if(u){const{base:t,config:e}=function(t,n){if(Array.isArray(n))return{base:"/",config:n};for(const r in n)if(0===(e=t,/(\.html|\/)$/.test(e)?e:e+"/").indexOf(encodeURI(r)))return{base:r,config:n[r]};var e;return{}}(n,u);return e?e.map(n=>function t(n,e,r,i=1){if("string"==typeof n)return h(e,n,r);if(Array.isArray(n))return Object.assign(h(e,n[0],r),{title:n[1]});{i>3&&console.error("[vuepress] detected a too deep nested sidebar group.");const o=n.children||[];return 0===o.length&&n.path?Object.assign(h(e,n.path,r),{title:n.title}):{type:"group",path:n.path,title:n.title,sidebarDepth:n.sidebarDepth,children:o.map(n=>t(n,e,r,i+1)),collapsable:!1!==n.collapsable}}}(n,i,t)):[]}return[]}function b(t){let n;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?n=t:n&&(n.children||(n.children=[])).push(t)}),t.filter(t=>2===t.level)}function g(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},240:function(t,n,e){},250:function(t,n,e){"use strict";e.r(n);var r=e(239),i={props:{item:{required:!0}},computed:{link(){return Object(r.b)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link}},methods:{isExternal:r.f,isMailto:r.g,isTel:r.h,focusoutAction(){this.$emit("focusout")}}},o=(e(252),e(14)),s=Object(o.a)(i,(function(){var t=this,n=t._self._c;return t.isExternal(t.link)?n("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.isMailto(t.link)||t.isTel(t.link)?null:"_blank",rel:t.isMailto(t.link)||t.isTel(t.link)?null:"noopener noreferrer"},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),n("OutboundLink")],1):n("router-link",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(n){return t.focusoutAction.apply(null,arguments)}}},[t._v(t._s(t.item.text))])}),[],!1,null,"34dbfd23",null);n.default=s.exports},252:function(t,n,e){"use strict";e(240)}}]); \ No newline at end of file diff --git a/assets/js/21.7d54624c.js b/assets/js/21.7d54624c.js new file mode 100644 index 00000000..c4c04b97 --- /dev/null +++ b/assets/js/21.7d54624c.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[21,20],{239:function(t,n,e){"use strict";e.d(n,"d",(function(){return r})),e.d(n,"a",(function(){return o})),e.d(n,"i",(function(){return s})),e.d(n,"f",(function(){return c})),e.d(n,"g",(function(){return l})),e.d(n,"h",(function(){return a})),e.d(n,"b",(function(){return f})),e.d(n,"e",(function(){return p})),e.d(n,"k",(function(){return h})),e.d(n,"l",(function(){return d})),e.d(n,"c",(function(){return b})),e.d(n,"j",(function(){return g}));e(89);const r=/#.*$/,i=/\.(md|html)$/,o=/\/$/,s=/^[a-z]+:/i;function u(t){return decodeURI(t).replace(r,"").replace(i,"")}function c(t){return s.test(t)}function l(t){return/^mailto:/.test(t)}function a(t){return/^tel:/.test(t)}function f(t){if(c(t))return t;const n=t.match(r),e=n?n[0]:"",i=u(t);return o.test(i)?t:i+".html"+e}function p(t,n){const e=t.hash,i=function(t){const n=t.match(r);if(n)return n[0]}(n);if(i&&e!==i)return!1;return u(t.path)===u(n)}function h(t,n,e){if(c(n))return{type:"external",path:n};e&&(n=function(t,n,e){const r=t.charAt(0);if("/"===r)return t;if("?"===r||"#"===r)return n+t;const i=n.split("/");e&&i[i.length-1]||i.pop();const o=t.replace(/^\//,"").split("/");for(let t=0;t({type:"auto",title:n.title,basePath:t.path,path:t.path+"#"+n.slug,children:n.children||[]}))}]}(t);const u=s.sidebar||o.sidebar;if(u){const{base:t,config:e}=function(t,n){if(Array.isArray(n))return{base:"/",config:n};for(const r in n)if(0===(e=t,/(\.html|\/)$/.test(e)?e:e+"/").indexOf(encodeURI(r)))return{base:r,config:n[r]};var e;return{}}(n,u);return e?e.map(n=>function t(n,e,r,i=1){if("string"==typeof n)return h(e,n,r);if(Array.isArray(n))return Object.assign(h(e,n[0],r),{title:n[1]});{i>3&&console.error("[vuepress] detected a too deep nested sidebar group.");const o=n.children||[];return 0===o.length&&n.path?Object.assign(h(e,n.path,r),{title:n.title}):{type:"group",path:n.path,title:n.title,sidebarDepth:n.sidebarDepth,children:o.map(n=>t(n,e,r,i+1)),collapsable:!1!==n.collapsable}}}(n,i,t)):[]}return[]}function b(t){let n;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?n=t:n&&(n.children||(n.children=[])).push(t)}),t.filter(t=>2===t.level)}function g(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},240:function(t,n,e){},250:function(t,n,e){"use strict";e.r(n);var r=e(239),i={props:{item:{required:!0}},computed:{link(){return Object(r.b)(this.item.link)},exact(){return this.$site.locales?Object.keys(this.$site.locales).some(t=>t===this.link):"/"===this.link}},methods:{isExternal:r.f,isMailto:r.g,isTel:r.h,focusoutAction(){this.$emit("focusout")}}},o=(e(252),e(14)),s=Object(o.a)(i,(function(){var t=this,n=t._self._c;return t.isExternal(t.link)?n("a",{staticClass:"nav-link external",attrs:{href:t.link,target:t.isMailto(t.link)||t.isTel(t.link)?null:"_blank",rel:t.isMailto(t.link)||t.isTel(t.link)?null:"noopener noreferrer"},on:{focusout:t.focusoutAction}},[t._v("\n "+t._s(t.item.text)+"\n "),n("OutboundLink")],1):n("router-link",{staticClass:"nav-link",attrs:{to:t.link,exact:t.exact},nativeOn:{focusout:function(n){return t.focusoutAction.apply(null,arguments)}}},[t._v(t._s(t.item.text))])}),[],!1,null,"34dbfd23",null);n.default=s.exports},252:function(t,n,e){"use strict";e(240)}}]); \ No newline at end of file diff --git a/assets/js/22.e65379f3.js b/assets/js/22.e65379f3.js new file mode 100644 index 00000000..0f496abb --- /dev/null +++ b/assets/js/22.e65379f3.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[22],{269:function(t,e,n){},275:function(t,e,n){"use strict";n.r(e);n(288);var s=n(14),c=Object(s.a)({},(function(){this._self._c;return this._m(0)}),[function(){var t=this._self._c;return t("div",{staticClass:"banner"},[t("a",{attrs:{href:"https://opencollective.com/codeceptjs"}},[this._v("CodeceptJS is on OpenCollective! Support us 💖")])])}],!1,null,"436508ca",null);e.default=c.exports},288:function(t,e,n){"use strict";n(269)}}]); \ No newline at end of file diff --git a/assets/js/23.a59d4566.js b/assets/js/23.a59d4566.js new file mode 100644 index 00000000..bb2cf64e --- /dev/null +++ b/assets/js/23.a59d4566.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[23],{289:function(t,a,i){},299:function(t,a,i){"use strict";i(289)},313:function(t,a,i){"use strict";i.r(a);var e={data:()=>({slideComp:null,carouselComp:null,nextLabel:"",prevLabel:""}),mounted(){i.e(9).then(i.t.bind(null,326,7)).then(t=>{this.slideComp=t.Slide,this.carouselComp=t.Carousel})}},s=(i(299),i(14)),l=Object(s.a)(e,(function(){var t=this,a=t._self._c;return a("div",{staticClass:"slider"},[t.carouselComp?a(t.carouselComp,{tag:"carousel",attrs:{navigationEnabled:!0,autoplayTimeout:1e4,autoplay:!1,"per-page":1,"navigation-next-label":t.nextLabel,"navigation-prev-label":t.prevLabel,"center-mode":!0,perPageCustom:[[768,2],[1024,3]]}},[a(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[a("div",{staticClass:"slide"},[a("img",{attrs:{src:"/img/companies/doxyme.png",title:"Doxy.me",alt:"Doxy.me"}})])]),t._v(" "),a(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[a("div",{staticClass:"slide"},[a("img",{staticClass:"rounded",attrs:{src:"/img/companies/zenitech.png",title:"Zenitech",alt:"Zenitech"}})])]),t._v(" "),a(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[a("div",{staticClass:"slide"},[a("img",{staticClass:"rounded",staticStyle:{"max-height":"95px"},attrs:{src:"/img/companies/kiabi.png",title:"Kiabi",alt:"Kiabi"}})])]),t._v(" "),a(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[a("div",{staticClass:"slide"},[a("img",{staticClass:"rounded mynd-img",staticStyle:{"max-height":"65px"},attrs:{src:"/img/companies/mynd.png",title:"Mynd",alt:"Mynd"}})])]),t._v(" "),a(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[a("div",{staticClass:"slide"},[a("img",{staticClass:"rounded",staticStyle:{background:"rgb(143 156 150)",padding:"10px","max-height":"75px"},attrs:{src:"/img/companies/gen3.png",title:"Gen3",alt:"Gen3"}})])]),t._v(" "),a(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[a("div",{staticClass:"slide"},[a("img",{staticClass:"rounded",attrs:{src:"/img/companies/isotipo.png",title:"Gamelearn",alt:"Gamelearn"}})])]),t._v(" "),a(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[a("div",{staticClass:"slide"},[a("img",{staticClass:"rounded",attrs:{src:"/img/companies/BC_LogoScreen_C.jpg",title:"Betclick",alt:"Betclick"}})])])],1):t._e()],1)}),[],!1,null,"59131a2e",null);a.default=l.exports}}]); \ No newline at end of file diff --git a/assets/js/24.683f87fe.js b/assets/js/24.683f87fe.js new file mode 100644 index 00000000..6f356900 --- /dev/null +++ b/assets/js/24.683f87fe.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[24],{241:function(t,e,n){},249:function(t,e,n){"use strict";n.r(e);var s={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},i=(n(253),n(14)),o=Object(i.a)(s,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=o.exports},253:function(t,e,n){"use strict";n(241)}}]); \ No newline at end of file diff --git a/assets/js/25.97e55767.js b/assets/js/25.97e55767.js new file mode 100644 index 00000000..9b621a3b --- /dev/null +++ b/assets/js/25.97e55767.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[25],{270:function(t,e,s){},272:function(t,e,s){"use strict";s.r(e);var i={data:()=>({year:(new Date).getFullYear()})},r=(s(290),s(14)),c=Object(r.a)(i,(function(){var t=this,e=t._self._c;return e("footer",[e("section",[e("div",{staticClass:"col"},[e("h4",[t._v("Docs")]),t._v(" "),e("ul",[e("li",[e("router-link",{attrs:{to:"/quickstart"}},[t._v("Quickstart")])],1),t._v(" "),e("li",[e("router-link",{attrs:{to:"/basics"}},[t._v("Getting Started")])],1),t._v(" "),e("li",[e("router-link",{attrs:{to:"/playwright"}},[t._v("CodeceptJS & Playwright")])],1),t._v(" "),e("li",[e("router-link",{attrs:{to:"/puppeteer"}},[t._v("CodeceptJS & WebDriver")])],1)])]),t._v(" "),t._m(0),t._v(" "),t._m(1),t._v(" "),t._m(2)]),t._v(" "),e("div",{staticClass:"copyright"},[e("h5",[t._v("CodeceptJS - supercharged end 2 end testing framework for NodeJS")]),t._v("\n © "+t._s(t.year)+"\n ")])])}),[function(){var t=this,e=t._self._c;return e("div",{staticClass:"col"},[e("h4",[t._v("Community")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS"}},[t._v("GitHub")])]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/discussions"}},[t._v("GitHub discussions")])]),t._v(" "),e("li",[e("a",{attrs:{href:"https://bit.ly/chat-codeceptjs"}},[t._v("Slack Chat")])]),t._v(" "),e("li",[e("a",{attrs:{href:"https://codecept.discourse.group/"}},[t._v("Forum")])]),t._v(" "),e("li",[e("a",{attrs:{href:"https://twitter.com/codeceptjs"}},[t._v("Twitter")])])])])},function(){var t=this._self._c;return t("div",{staticClass:"col"},[t("h4",{staticClass:"important"},[this._v("Commercial Support")]),this._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://sdclabs.com/codeceptjs?utm_source=codecept.io&utm_medium=footer&utm_term=link&utm_campaign=reference"}},[this._v("Consulting")])]),this._v(" "),t("li",[t("a",{attrs:{href:"https://sdclabs.com/trainings/web-automation-codeceptjs?utm_source=codecept.io&utm_medium=top_menu&utm_term=link&utm_campaign=reference"}},[this._v("Trainings")])]),this._v(" "),t("li",[t("a",{attrs:{href:"https://sdclabs.com/#services"}},[this._v("Hire Engineers")])])])])},function(){var t=this._self._c;return t("div",{staticClass:"col"},[t("a",{attrs:{href:"https://testomat.io"}},[t("h4",[this._v("Try Testomat.io →")]),this._v(" "),t("p",[this._v("Powerful "),t("b",[this._v("Test Case Management")]),this._v(" for CodeceptJS from its authors")])])])}],!1,null,"5616cc4e",null);e.default=c.exports},290:function(t,e,s){"use strict";s(270)}}]); \ No newline at end of file diff --git a/assets/js/26.52d000b1.js b/assets/js/26.52d000b1.js new file mode 100644 index 00000000..db262423 --- /dev/null +++ b/assets/js/26.52d000b1.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[26],{247:function(t,s,e){},265:function(t,s,e){"use strict";e(247)},268:function(t,s,e){"use strict";e.r(s);e(265);var r=e(14),i=Object(r.a)({},(function(){var t=this,s=t._self._c;return s("div",{staticClass:"sidebar"},[s("div",{staticClass:"sidebar-wrapper"},[s("h4",[t._v("More Information")]),t._v(" "),s("p",[s("router-link",{attrs:{to:"/videos"}},[t._v("Videos")])],1),t._v(" "),s("p",[s("router-link",{attrs:{to:"/books"}},[t._v("Books & Posts")])],1),t._v(" "),s("p",[s("router-link",{attrs:{to:"/examples"}},[t._v("Examples")])],1),t._v(" "),t._m(0),t._v(" "),s("hr"),t._v(" "),t._m(1),t._v(" "),t._m(2),t._v(" "),t._m(3),t._v(" "),t._m(4)])])}),[function(){var t=this._self._c;return t("p",[t("a",{attrs:{href:"https://codecept.discourse.group/c/cookbook"}},[this._v("Cookbook →")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://sdclabs.com/codeceptjs?utm_source=codecept.io&utm_medium=right&utm_term=link&utm_campaign=reference"}},[this._v("\n Commercial Services →\n ")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://sdclabs.com/trainings/web-automation-codeceptjs?utm_source=codecept.io&utm_medium=rigth&utm_term=link&utm_campaign=reference"}},[this._v("\n Trainings →\n ")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://testomat.io"}},[this._v("\n Testomat.io →\n ")]),t("br"),this._v(" "),t("small",[t("b",[this._v("Plan your end 2 end tests")]),this._v(", collaborate, synchronize with code & get reports!"),t("br"),this._v("\n Join Testomat.io while it is in beta and get a huge discount!")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://opencollective.com/codeceptjs"}},[this._v("\n Support us via OpenCollective!\n ")])])}],!1,null,"0dc4070a",null);s.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/27.8d189b77.js b/assets/js/27.8d189b77.js new file mode 100644 index 00000000..20f23ce4 --- /dev/null +++ b/assets/js/27.8d189b77.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[27],{293:function(t,c,n){},301:function(t,c,n){"use strict";n(293)},315:function(t,c,n){"use strict";n.r(c);n(301);var s=n(14),i=Object(s.a)({},(function(){var t=this,c=t._self._c;return c("div",{staticClass:"sidebar-button",on:{click:function(c){return t.$emit("toggle-sidebar")}}},[c("svg",{staticClass:"icon",attrs:{xmlns:"http://www.w3.org/2000/svg","aria-hidden":"true",viewBox:"0 0 448 512"}},[c("path",{attrs:{fill:"#fff",d:"M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"}})])])}),[],!1,null,null,null);c.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/28.a0ec19a0.js b/assets/js/28.a0ec19a0.js new file mode 100644 index 00000000..9674094f --- /dev/null +++ b/assets/js/28.a0ec19a0.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[28],{291:function(t,e,s){},300:function(t,e,s){"use strict";s(291)},314:function(t,e,s){"use strict";s.r(e);var a={data:()=>({slideComp:null,carouselComp:null,nextLabel:"",prevLabel:""}),mounted(){s.e(9).then(s.t.bind(null,326,7)).then(t=>{this.slideComp=t.Slide,this.carouselComp=t.Carousel})}},i=(s(300),s(14)),l=Object(i.a)(a,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"slider"},[t.carouselComp?e(t.carouselComp,{tag:"carousel",attrs:{navigationEnabled:!0,autoplayTimeout:1e4,autoplay:!0,"per-page":1,"navigation-next-label":t.nextLabel,"navigation-prev-label":t.prevLabel,"center-mode":!0}},[e(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[e("div",{staticClass:"slide"},[e("img",{attrs:{src:"/img/pause.gif",alt:"pause"}}),t._v(" "),e("div",[e("Content",{attrs:{"slot-key":"pause"}})],1)])]),t._v(" "),e(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[e("div",{staticClass:"slide"},[e("img",{attrs:{src:"/img/test.gif",alt:"test"}}),t._v(" "),e("div",[e("Content",{attrs:{"slot-key":"run"}})],1)])]),t._v(" "),e(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[e("div",{staticClass:"slide"},[e("img",{attrs:{src:"/img/edit.gif",alt:"edit"}}),t._v(" "),e("div",[e("Content",{attrs:{"slot-key":"autocomplete"}})],1)])]),t._v(" "),e(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[e("div",{staticClass:"slide"},[e("img",{attrs:{src:"/img/codeceptui.gif",alt:"codeceptui"}}),t._v(" "),e("div",[e("Content",{attrs:{"slot-key":"ui"}}),t._v(" "),e("router-link",{staticClass:"button green",attrs:{to:"ui"}},[t._v("Try CodeceptUI →")])],1)])]),t._v(" "),e(t.slideComp,{tag:"slide",attrs:{"aria-hidden":"false"}},[e("div",{staticClass:"slide"},[e("img",{attrs:{src:"/img/new-test.gif",alt:"new-test"}}),t._v(" "),e("div",[e("Content",{attrs:{"slot-key":"write"}}),t._v(" "),e("router-link",{staticClass:"button green",attrs:{to:"ui"}},[t._v("Try CodeceptUI →")])],1)])])],1):t._e()],1)}),[],!1,null,null,null);e.default=l.exports}}]); \ No newline at end of file diff --git a/assets/js/29.25166714.js b/assets/js/29.25166714.js new file mode 100644 index 00000000..b1f25ca9 --- /dev/null +++ b/assets/js/29.25166714.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[29],{260:function(t,n,s){},280:function(t,n,s){"use strict";s(260)},285:function(t,n,s){"use strict";s.r(n);var a={name:"Subbar"},e=(s(280),s(14)),i=Object(e.a)(a,(function(){this._self._c;return this._m(0)}),[function(){var t=this._self._c;return t("header",{staticClass:"sub-bar"},[t("div",{staticClass:"message"},[t("a",{attrs:{target:"_blank",href:"https://stand-with-ukraine.pp.ua"}},[this._v("🇺🇦 CodeceptJS was created in Ukraine.\n #StandWithUkraine")]),this._v(" "),t("p")])])}],!1,null,null,null);n.default=i.exports}}]); \ No newline at end of file diff --git a/assets/js/3.188649f0.js b/assets/js/3.188649f0.js new file mode 100644 index 00000000..023178a3 --- /dev/null +++ b/assets/js/3.188649f0.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[3,26,29],{242:function(t,e,s){},243:function(t,e,s){},244:function(t,e){t.exports=function(t){return null==t}},245:function(t,e,s){},246:function(t,e,s){},247:function(t,e,s){},248:function(t,e,s){},251:function(t,e,s){"use strict";s.r(e);var a=s(267),i=s(261),n=s(239);function r(t,e){return"group"===e.type&&e.children.some(e=>"group"===e.type?r(t,e):"page"===e.type&&Object(n.e)(t,e.path))}var o={name:"SidebarLinks",components:{SidebarGroup:a.default,SidebarLink:i.default},props:["items","depth","sidebarDepth"],data:()=>({openGroupIndex:0}),created(){this.refreshIndex()},watch:{$route(){this.refreshIndex()}},methods:{refreshIndex(){const t=function(t,e){for(let s=0;s-1&&(this.openGroupIndex=t)},toggleGroup(t){this.openGroupIndex=t===this.openGroupIndex?-1:t},isActive(t){return Object(n.e)(this.$route,t.regularPath)}}},l=s(14),c=Object(l.a)(o,(function(){var t=this,e=t._self._c;return t.items.length?e("ul",{staticClass:"sidebar-links"},t._l(t.items,(function(s,a){return e("li",{key:a},["group"===s.type?e("SidebarGroup",{attrs:{item:s,open:a===t.openGroupIndex,collapsable:s.collapsable||s.collapsible,depth:t.depth},on:{toggle:function(e){return t.toggleGroup(a)}}}):e("SidebarLink",{attrs:{sidebarDepth:t.sidebarDepth,item:s}})],1)})),0):t._e()}),[],!1,null,null,null);e.default=c.exports},255:function(t,e,s){},256:function(t,e,s){"use strict";s(242)},257:function(t,e,s){"use strict";s(243)},258:function(t,e,s){},259:function(t,e,s){},260:function(t,e,s){},261:function(t,e,s){"use strict";s.r(e);var a=s(239);function i(t,e,s,a){return t("router-link",{props:{to:e,activeClass:"",exactActiveClass:""},class:{active:a,"sidebar-link":!0}},s)}function n(t,e,s,r,o,l=1){return!e||l>o?null:t("ul",{class:"sidebar-sub-headers"},e.map(e=>{const c=Object(a.e)(r,s+"#"+e.slug);return t("li",{class:"sidebar-sub-header"},[i(t,s+"#"+e.slug,e.title,c),n(t,e.children,s,r,o,l+1)])}))}var r={functional:!0,props:["item","sidebarDepth"],render(t,{parent:{$page:e,$site:s,$route:r,$themeConfig:o,$themeLocaleConfig:l},props:{item:c,sidebarDepth:u}}){const d=Object(a.e)(r,c.path),p="auto"===c.type?d||c.children.some(t=>Object(a.e)(r,c.basePath+"#"+t.slug)):d,h="external"===c.type?function(t,e,s){return t("a",{attrs:{href:e,target:"_blank",rel:"noopener noreferrer"},class:{"sidebar-link":!0}},[s,t("OutboundLink")])}(t,c.path,c.title||c.path):i(t,c.path,c.title||c.path,p),f=[e.frontmatter.sidebarDepth,u,l.sidebarDepth,o.sidebarDepth,1].find(t=>void 0!==t),v=l.displayAllHeaders||o.displayAllHeaders;if("auto"===c.type)return[h,n(t,c.children,c.basePath,r,f)];if((p||v)&&c.headers&&!a.d.test(c.path)){return[h,n(t,Object(a.c)(c.headers),c.path,r,f)]}return h}},o=(s(256),s(257),s(14)),l=Object(o.a)(r,void 0,void 0,!1,null,"a68ca4e6",null);e.default=l.exports},262:function(t,e,s){"use strict";s(245)},263:function(t,e,s){var a=s(11),i=s(4),n=s(10);t.exports=function(t){return"string"==typeof t||!i(t)&&n(t)&&"[object String]"==a(t)}},264:function(t,e,s){"use strict";s(246)},265:function(t,e,s){"use strict";s(247)},266:function(t,e,s){"use strict";s(248)},267:function(t,e,s){"use strict";s.r(e);var a=s(239),i={name:"SidebarGroup",props:["item","open","collapsable","depth"],components:{DropdownTransition:s(249).default},beforeCreate(){this.$options.components.SidebarLinks=s(251).default},methods:{isActive:a.e}},n=(s(266),s(14)),r=Object(n.a)(i,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"sidebar-group",class:[{collapsable:t.collapsable,"is-sub-group":0!==t.depth},"depth-"+t.depth]},[t.item.path?e("router-link",{staticClass:"sidebar-heading clickable",class:{open:t.open,active:t.isActive(t.$route,t.item.path)},attrs:{to:t.item.path},nativeOn:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"open":""}):t._e()]):e("p",{staticClass:"sidebar-heading",class:{open:t.open},on:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"open":""}):t._e()]),t._v(" "),e("DropdownTransition",[t.open||!t.collapsable?e("SidebarLinks",{staticClass:"sidebar-group-items",attrs:{items:t.item.children,sidebarDepth:t.item.sidebarDepth,depth:t.depth+1}}):t._e()],1)],1)}),[],!1,null,null,null);e.default=r.exports},268:function(t,e,s){"use strict";s.r(e);s(265);var a=s(14),i=Object(a.a)({},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"sidebar"},[e("div",{staticClass:"sidebar-wrapper"},[e("h4",[t._v("More Information")]),t._v(" "),e("p",[e("router-link",{attrs:{to:"/videos"}},[t._v("Videos")])],1),t._v(" "),e("p",[e("router-link",{attrs:{to:"/books"}},[t._v("Books & Posts")])],1),t._v(" "),e("p",[e("router-link",{attrs:{to:"/examples"}},[t._v("Examples")])],1),t._v(" "),t._m(0),t._v(" "),e("hr"),t._v(" "),t._m(1),t._v(" "),t._m(2),t._v(" "),t._m(3),t._v(" "),t._m(4)])])}),[function(){var t=this._self._c;return t("p",[t("a",{attrs:{href:"https://codecept.discourse.group/c/cookbook"}},[this._v("Cookbook →")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://sdclabs.com/codeceptjs?utm_source=codecept.io&utm_medium=right&utm_term=link&utm_campaign=reference"}},[this._v("\n Commercial Services →\n ")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://sdclabs.com/trainings/web-automation-codeceptjs?utm_source=codecept.io&utm_medium=rigth&utm_term=link&utm_campaign=reference"}},[this._v("\n Trainings →\n ")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://testomat.io"}},[this._v("\n Testomat.io →\n ")]),t("br"),this._v(" "),t("small",[t("b",[this._v("Plan your end 2 end tests")]),this._v(", collaborate, synchronize with code & get reports!"),t("br"),this._v("\n Join Testomat.io while it is in beta and get a huge discount!")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://opencollective.com/codeceptjs"}},[this._v("\n Support us via OpenCollective!\n ")])])}],!1,null,"0dc4070a",null);e.default=i.exports},273:function(t,e,s){"use strict";s.r(e);var a=s(244),i=s.n(a),n=s(239),r={name:"PageEdit",computed:{lastUpdated(){return this.$page.lastUpdated},lastUpdatedText(){return"string"==typeof this.$themeLocaleConfig.lastUpdated?this.$themeLocaleConfig.lastUpdated:"string"==typeof this.$site.themeConfig.lastUpdated?this.$site.themeConfig.lastUpdated:"Last Updated"},editLink(){const t=i()(this.$page.frontmatter.editLink)?this.$site.themeConfig.editLinks:this.$page.frontmatter.editLink,{repo:e,docsDir:s="",docsBranch:a="master",docsRepo:n=e}=this.$site.themeConfig;return t&&n&&this.$page.relativePath?this.createEditLink(e,n,s,a,this.$page.relativePath):null},editLinkText(){return this.$themeLocaleConfig.editLinkText||this.$site.themeConfig.editLinkText||"Edit this page"}},methods:{createEditLink(t,e,s,a,i){if(/bitbucket.org/.test(t)){return(n.i.test(e)?e:t).replace(n.a,"")+"/src"+`/${a}/`+(s?s.replace(n.a,"")+"/":"")+i+`?mode=edit&spa=0&at=${a}&fileviewer=file-view-default`}return(n.i.test(e)?e:"https://github.com/"+e).replace(n.a,"")+"/edit"+`/${a}/`+(s?s.replace(n.a,"")+"/":"")+i}}},o=(s(262),s(14)),l=Object(o.a)(r,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"page-edit"},[t.editLink?e("div",{staticClass:"edit-link"},[e("a",{attrs:{href:t.editLink,target:"_blank",rel:"noopener noreferrer"}},[t._v(t._s(t.editLinkText))]),t._v(" "),e("OutboundLink")],1):t._e(),t._v(" "),t.lastUpdated?e("div",{staticClass:"last-updated"},[e("span",{staticClass:"prefix"},[t._v(t._s(t.lastUpdatedText)+":")]),t._v(" "),e("span",{staticClass:"time"},[t._v(t._s(t.lastUpdated))])]):t._e()])}),[],!1,null,null,null);e.default=l.exports},274:function(t,e,s){"use strict";s.r(e);s(89);var a=s(239),i=s(263),n=s.n(i),r=s(244),o=s.n(r),l={name:"PageNav",props:["sidebarItems"],computed:{prev(){return u(c.PREV,this)},next(){return u(c.NEXT,this)}}};const c={NEXT:{resolveLink:function(t,e){return d(t,e,1)},getThemeLinkConfig:({nextLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.next},PREV:{resolveLink:function(t,e){return d(t,e,-1)},getThemeLinkConfig:({prevLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.prev}};function u(t,{$themeConfig:e,$page:s,$route:i,$site:r,sidebarItems:l}){const{resolveLink:c,getThemeLinkConfig:u,getPageLinkConfig:d}=t,p=u(e),h=d(s),f=o()(h)?p:h;return!1===f?void 0:n()(f)?Object(a.k)(r.pages,f,i.path):c(s,l)}function d(t,e,s){const a=[];!function t(e,s){for(let a=0,i=e.length;a({isSidebarOpen:!1}),computed:{shouldShowNavbar(){const{themeConfig:t}=this.$site,{frontmatter:e}=this.$page;return!1!==e.navbar&&!1!==t.navbar&&(this.$title||t.logo||t.repo||t.nav||this.$themeLocaleConfig.nav)},shouldShowSidebar(){const{frontmatter:t}=this.$page;return!t.home&&!1!==t.sidebar&&this.sidebarItems.length},sidebarItems(){return Object(l.l)(this.$page,this.$page.regularPath,this.$site,this.$localePath)},pageClasses(){const t=this.$page.frontmatter.pageClass;return[{"no-navbar":!this.shouldShowNavbar,"sidebar-open":this.isSidebarOpen,"no-sidebar":!this.shouldShowSidebar},t]}},mounted(){this.$router.afterEach(()=>{this.isSidebarOpen=!1})},methods:{toggleSidebar(t){this.isSidebarOpen="boolean"==typeof t?t:!this.isSidebarOpen,this.$emit("toggle-sidebar",this.isSidebarOpen)},onTouchStart(t){this.touchStart={x:t.changedTouches[0].clientX,y:t.changedTouches[0].clientY}},onTouchEnd(t){const e=t.changedTouches[0].clientX-this.touchStart.x,s=t.changedTouches[0].clientY-this.touchStart.y;Math.abs(e)>Math.abs(s)&&Math.abs(e)>40&&(e>0&&this.touchStart.x<=80?this.toggleSidebar(!0):this.toggleSidebar(!1))}}},p=(s(322),s(323),s(14)),h=Object(p.a)(d,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"theme-container sectionLayout",class:t.pageClasses,on:{touchstart:t.onTouchStart,touchend:t.onTouchEnd}},[t.shouldShowNavbar?e("Navbar",{on:{"toggle-sidebar":t.toggleSidebar}}):t._e(),t._v(" "),e("Subbar"),t._v(" "),e("div",{staticClass:"hero"}),t._v(" "),e("div",{staticClass:"container post"},[e("article",{staticClass:"content"},[e("Content")],1)]),t._v(" "),t.$frontmatter.sidebar?e("div",{staticClass:"sidebar"},[e("Content",{attrs:{"slot-key":"sidebar"}})],1):t._e(),t._v(" "),e("Sidebar",{attrs:{items:t.sidebarItems},on:{"toggle-sidebar":t.toggleSidebar}},[t._t("sidebar-top"),t._v(" "),t._t("sidebar-bottom")],2),t._v(" "),e("div",{staticClass:"sidebar-mask",on:{click:function(e){return t.toggleSidebar(!1)}}}),t._v(" "),e("Banner"),t._v(" "),e("Footer")],1)}),[],!1,null,"24c39123",null);e.default=h.exports}}]); \ No newline at end of file diff --git a/assets/js/30.f52df054.js b/assets/js/30.f52df054.js new file mode 100644 index 00000000..354e4ece --- /dev/null +++ b/assets/js/30.f52df054.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[30],{333:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"acceptance-testing"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#acceptance-testing"}},[t._v("#")]),t._v(" Acceptance Testing")]),t._v(" "),s("p",[t._v("How does your client, manager, or tester, or any other non-technical person, know your web application is working? By opening the browser, accessing a site, clicking on links, filling in the forms, and actually seeing the content on a web page.")]),t._v(" "),s("p",[t._v("Acceptance (also called End to End) tests can cover standard but complex scenarios from a user's perspective. With acceptance tests you can be confident that users, following all defined scenarios, won't get errors. We check "),s("strong",[t._v("not just functionality of application but a user interface")]),t._v(" (UI) as well.")]),t._v(" "),s("p",[t._v("By default CodeceptJS uses "),s("RouterLink",{attrs:{to:"/helpers/WebDriver/"}},[t._v("WebDriver")]),t._v(" helper and "),s("strong",[t._v("Selenium")]),t._v(" to automate browser. Within web page you can locate elements, interact with them, and check that expected elements are present on a page.\nHowever, you can also choose "),s("a",{attrs:{href:"/helpers/Puppeteer"}},[t._v("Puppeteer")]),t._v(", "),s("a",{attrs:{href:"/helpers/Nightmare"}},[t._v("Nightmare")]),t._v(" or "),s("a",{attrs:{href:"/helpers/Protractor"}},[t._v("Protractor")]),t._v(" helpers, driven by corresponding libraries.\nNo matter of helper and library you use for acceptance testing, CodeceptJS should execute same actions in similar manner.")],1),t._v(" "),s("p",[t._v("In case of CodeceptJS you can be sure that in code it will be as easy as it sounds. You just describe a test scenario with JavaScript DSL and allow the framework to handle the rest.")]),t._v(" "),s("p",[t._v("Within web page you can locate elements, interact with them, and check that expected elements are present on a page. That is what a test look like.\nThat is what a test look like.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Username'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'123456'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Welcome, John'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("This is how we can check that login form of a simple web application works. At first we opened "),s("code",[t._v("/login")]),t._v(" page, then filled forms and in the end we saw the greetings text.")]),t._v(" "),s("h2",{attrs:{id:"locating-element"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#locating-element"}},[t._v("#")]),t._v(" Locating Element")]),t._v(" "),s("p",[t._v("Element can be found by CSS or XPath locators. Practically every steps\nin WebDriver helper accept them both.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// element with CSS class user")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'//button[contains(., \"press me\")]'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// button")]),t._v("\n")])])]),s("p",[t._v("By default CodeceptJS tries to guess the locator type.\nIn order to specify exact locator type you can pass a hash called "),s("strong",[t._v("strict locator")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("css")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'div.user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("xpath")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'//div[@class=user]'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Strict locators allow to specify additional locator types:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate form element by name")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate element by id")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("permalink")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'users'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("In "),s("a",{attrs:{href:"http://codecept.io/mobile/#locating-elements",target:"_blank",rel:"noopener noreferrer"}},[t._v("mobile testing"),s("OutboundLink")],1),t._v(" you can use "),s("code",[t._v("~")]),t._v(" to specify accessibility id to locate an element. In web application you can locate element by their "),s("code",[t._v("aria-label")]),t._v(" value.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate element by [aria-label] attribute in web")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// or by accessibility id in mobile")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~username'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"clicking"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#clicking"}},[t._v("#")]),t._v(" Clicking")]),t._v(" "),s("p",[t._v("CodeceptJS provides a flexible syntax to specify an element to click.")]),t._v(" "),s("p",[t._v("By default CodeceptJS tries to find button or link with exact text on it")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// search for link or button")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("If none found, CodeceptJS tries to find link or button containing that text. In case an image is clickable its "),s("code",[t._v("alt")]),t._v(" attribute will be checked for text inclusion. Form buttons will also be searched by name.")]),t._v(" "),s("p",[t._v("To narrow down the results you can specify a context in second parameter.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.nav'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// search only in .nav")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("css")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'footer'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// search only in footer")]),t._v("\n")])])]),s("p",[t._v("To skip the global search pass exact strict locator (or start locator with "),s("code",[t._v("//")]),t._v(" or "),s("code",[t._v(".")]),t._v(" or "),s("code",[t._v("#")]),t._v(").\nIn this case you are not limited to buttons and links. Any element found by that locator is clicked.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// click element by CSS")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#signup'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// click element located by name inside a form")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'submit'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#user>form'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"filling-fields"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#filling-fields"}},[t._v("#")]),t._v(" Filling Fields")]),t._v(" "),s("p",[t._v("Clicking the links is not what takes the most time during testing a web site. If your site consists only of links you can skip test automation. The most routine waste of time goes into the testing of forms. CodeceptJS provides several ways of doing that.")]),t._v(" "),s("p",[t._v("Let's submit this sample form for a test:")]),t._v(" "),s("div",{staticClass:"language-html extra-class"},[s("pre",{pre:!0,attrs:{class:"language-html"}},[s("code",[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("form")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("method")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("post"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("action")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("/update"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("update_form"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("label")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("user_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("Name"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("text"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("user[name]"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("user_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("label")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("user_email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("Email"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("text"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("user[email]"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("user_email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("label")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("user_gender"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("Gender"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("select")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("user_gender"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("user[gender]"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("option")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("value")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("m"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("Male"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("option")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("value")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("f"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("Female"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("submit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("submitButton"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("value")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Update"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])]),s("p",[t._v('We need to fill in all those fields and click "Update" button. CodeceptJS matches form elements by their label, name, or by CSS or XPath locators.')]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// we are using label to match user_name field")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Name'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Miles'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// we can use input name")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user[email]'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'miles@davis.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// select element by label, choose option by text")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("selectOption")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Gender'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Male'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// click 'Update' button, found by text")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Update'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Alternative scenario:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// we are using CSS")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#user_name'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Miles'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#user_email'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'miles@davis.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// select element by label, option by value")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("selectOption")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#user_gender'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'m'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// click 'Update' button, found by name")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'submitButton'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#update_form'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("To fill in sensitive data use "),s("code",[t._v("secret")]),t._v(" function:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("secret")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'123456'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"assertions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#assertions"}},[t._v("#")]),t._v(" Assertions")]),t._v(" "),s("p",[t._v("In order to verify the expected behavior of a web application, web page connects should be checked.\nCodeceptJS provides built-in assertions for that. They start with "),s("code",[t._v("see")]),t._v(" (or "),s("code",[t._v("dontSee")]),t._v(") prefix, as they describe user's current vision.")]),t._v(" "),s("p",[t._v("The most general and common assertion is "),s("code",[t._v("see")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Just a visible text on a page")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// text inside .msg element")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.msg'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// opposite")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSee")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Bye'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("You should provide a text as first argument, and optionally a locator to narrow the search context.")]),t._v(" "),s("p",[t._v("You can check that specific element exists (or not) on a page, as it was described in "),s("a",{attrs:{href:"#locating-element"}},[t._v("Locating Element")]),t._v(" section.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.notice'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.error'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Additional assertions:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeInCurrentUrl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/user/miles'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeInField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user[name]'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Miles'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeInTitle")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'My Website'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("To see all possible assertions see the helper's reference.")]),t._v(" "),s("h2",{attrs:{id:"grabbing"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#grabbing"}},[t._v("#")]),t._v(" Grabbing")]),t._v(" "),s("p",[t._v("Sometimes you need to retrieve a data from a page to use it in next steps of a scenario.\nImagine, application generates a password and you want to ensure that user can login using this password.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'login with generated password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'email'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'miles@davis.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Generate Password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" password "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabTextFrom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'email'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'miles@davis.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" password"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Log in!'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello, Miles'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("code",[t._v("grabTextFrom")]),t._v(" action is used here to retrieve text from an element. All actions starting with "),s("code",[t._v("grab")]),t._v(" prefix are expected to return data. In order to synchronize this step with a scenario you should pause test execution with "),s("code",[t._v("await")]),t._v(" keyword of ES6. To make it work your test should be written inside a async function (notice "),s("code",[t._v("async")]),t._v(" in its definition).")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'use page title'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" password "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabTextFrom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" password"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"waiting"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#waiting"}},[t._v("#")]),t._v(" Waiting")]),t._v(" "),s("p",[t._v("In modern web applications rendering is happen on client side.\nSometimes that may cause delays. A test may fail while trying to click an element which has not appeared on a page yet.\nTo handle this cases "),s("code",[t._v("wait*")]),t._v(" methods introduced.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#agree_button'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// secs")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// clicks a button only when it is visible")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#agree_button'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("More wait actions can be found in helper's reference.")]),t._v(" "),s("h2",{attrs:{id:"smartwait"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#smartwait"}},[t._v("#")]),t._v(" SmartWait")]),t._v(" "),s("p",[t._v("It is possible to wait for elements pragmatically. If a test uses element which is not on a page yet, CodeceptJS will wait for few extra seconds before failing. This feature is based on "),s("a",{attrs:{href:"http://www.seleniumhq.org/docs/04_webdriver_advanced.jsp#implicit-waits",target:"_blank",rel:"noopener noreferrer"}},[t._v("Implicit Wait"),s("OutboundLink")],1),t._v(" of Selenium. CodeceptJS enables implicit wait only when searching for a specific element and disables in all other cases. Thus, the performance of a test is not affected.")]),t._v(" "),s("p",[t._v("SmartWait can be enabled by setting wait option in WebDriver config.\nAdd "),s("code",[t._v('"smartWait": 5000')]),t._v(" to wait for additional 5s.")]),t._v(" "),s("p",[t._v("SmartWait works with a CSS/XPath locators in "),s("code",[t._v("click")]),t._v(", "),s("code",[t._v("seeElement")]),t._v(" and other methods. See where it is enabled and where is not:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// DISABLED, not a locator")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// DISABLED, not a specific locator")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'123456'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ENABLED, strict locator")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ENABLED, locator is CSS ID")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello, Davert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// DISABLED, Not a locator")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#userbar'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ENABLED")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// DISABLED, can't wait for element to hide")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeNumberOfElements")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'button.link'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// DISABLED, can wait only for one element")]),t._v("\n\n")])])]),s("p",[t._v("SmartWait doesn't check element for visibility, so tests may fail even element is on a page.")]),t._v(" "),s("p",[t._v("Usage example:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// we use smartWait: 5000 instead of")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// I.waitForElement('#click-me', 5);")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// to wait for element on page")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#click-me'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("If it's hard to define what to wait, it is recommended to use "),s("RouterLink",{attrs:{to:"/basics/#retries"}},[t._v("retries")]),t._v(" to rerun flaky steps.")],1),t._v(" "),s("h2",{attrs:{id:"iframes"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#iframes"}},[t._v("#")]),t._v(" IFrames")]),t._v(" "),s("p",[s("RouterLink",{attrs:{to:"/basics/#within"}},[t._v("within")]),t._v(" operator can be used to work inside IFrames. Special "),s("code",[t._v("frame")]),t._v(" locator is required to locate the iframe and get into its context.")],1),t._v(" "),s("p",[t._v("See example:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("within")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("frame")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"#editor"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Page'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Nested IFrames can be set by passing array "),s("em",[t._v("(WebDriver, Nightmare & Puppeteer only)")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("within")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("frame")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('".content"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"#editor"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Page'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"auto-login"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#auto-login"}},[t._v("#")]),t._v(" Auto Login")]),t._v(" "),s("p",[t._v("To share the same user session across different tests CodeceptJS provides "),s("a",{attrs:{href:"/plugins#autologin"}},[t._v("autoLogin plugin")]),t._v(". It simplifies login management and reduces time consuming login operations. Instead of filling in login form before each test it saves the cookies of a valid user session and reuses it for next tests. If a session expires or doesn't exist, logs in a user again.")]),t._v(" "),s("p",[t._v("This plugin requires some configuration but is very simple in use:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'do something with logged in user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" login"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("login")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Dashboard'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'h1'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("With "),s("code",[t._v("autoLogin")]),t._v(" plugin you can save cookies into a file and reuse same session on different runs.")]),t._v(" "),s("blockquote",[s("p",[t._v("Read more about setting up "),s("a",{attrs:{href:"/plugins#autologin"}},[t._v("autoLogin")])])]),t._v(" "),s("h2",{attrs:{id:"multiple-sessions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#multiple-sessions"}},[t._v("#")]),t._v(" Multiple Sessions")]),t._v(" "),s("p",[t._v("CodeceptJS allows to run several browser sessions inside a test. This can be useful for testing communication between users inside a system, for instance in chats. To open another browser use "),s("code",[t._v("session()")]),t._v(" function as shown in example:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'test app'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/chat'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'name'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Sign In'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello, davert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("session")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// another session started")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/chat'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'name'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Sign In'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello, john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// switching back to default session")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'message'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hi, john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// there is a message from current user")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'me: Hi, john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.messages'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("session")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// let's check if john received it")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert: Hi, john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.messages'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("code",[t._v("session")]),t._v(" function expects a first parameter to be a name of a session. You can switch back to session by using the same name.")]),t._v(" "),s("p",[t._v("You can override config for session by passing second parameter:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("session")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'firefox'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// run this steps in firefox")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("or just start session without switching to it. Call "),s("code",[t._v("session")]),t._v(" passing only its name:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'test'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// opens 3 additional browsers")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("session")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("session")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'mary'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("session")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'jane'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// switch to session by its name")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("session")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'mary'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[s("code",[t._v("session")]),t._v(" can return value which can be used in scenario:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside async function")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" val "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("session")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/info'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabTextFrom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("css")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'h1'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Description'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Function passed into session can use "),s("code",[t._v("I")]),t._v(", page objects, and any objects declared for the scenario.\nThis function can also be declared as async (but doesn't work as generator).")]),t._v(" "),s("p",[t._v("Also, you can use "),s("code",[t._v("within")]),t._v(" inside a session but you can't call session from inside "),s("code",[t._v("within")]),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"multiple-windows"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#multiple-windows"}},[t._v("#")]),t._v(" Multiple Windows")]),t._v(" "),s("p",[t._v("CodeceptJS allows to use several browser windows inside a test. Sometimes we are testing the functionality of websites that we cannot control, such as a closed-source managed package, and there are popups that either remain open for configuring data on the screen, or close as a result of clicking a window. We can use these functions in order to gain more control over which page is being tested with Codecept at any given time. For example:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" assert "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'assert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'should open main page of configured site, open a popup, switch to main page, then switch to popup, close popup, and go back to main page'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" handleBeforePopup "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabCurrentWindowHandle")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" urlBeforePopup "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabCurrentUrl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" allHandlesBeforePopup "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabAllWindowHandles")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("allHandlesBeforePopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Single Window'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("executeScript")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n window"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://www.w3schools.com/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'new window'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'toolbar=yes,scrollbars=yes,resizable=yes,width=400,height=400'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" allHandlesAfterPopup "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabAllWindowHandles")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("allHandlesAfterPopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Two Windows'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("switchToWindow")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("allHandlesAfterPopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" urlAfterPopup "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabCurrentUrl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("urlAfterPopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://www.w3schools.com/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Expected URL: Popup'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("handleBeforePopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" allHandlesAfterPopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Expected Window: Main Window'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("switchToWindow")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("handleBeforePopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" currentURL "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabCurrentUrl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("currentURL"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" urlBeforePopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Expected URL: Main URL'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("switchToWindow")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("allHandlesAfterPopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" urlAfterSwitchBack "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabCurrentUrl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("urlAfterSwitchBack"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://www.w3schools.com/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Expected URL: Popup'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("closeCurrentTab")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" allHandlesAfterPopupClosed "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabAllWindowHandles")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("allHandlesAfterPopupClosed"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Single Window'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" currentWindowHandle "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabCurrentWindowHandle")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("currentWindowHandle"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" allHandlesAfterPopup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Expected Window: Main Window'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("tag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@ProofOfConcept'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("tag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@grabAllWindowHandles'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("tag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@grabCurrentWindowHandle'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("tag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@switchToWindow'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/31.2bbbc1bd.js b/assets/js/31.2bbbc1bd.js new file mode 100644 index 00000000..57463cfa --- /dev/null +++ b/assets/js/31.2bbbc1bd.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[31],{332:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"advanced-usage"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#advanced-usage"}},[t._v("#")]),t._v(" Advanced Usage")]),t._v(" "),s("h2",{attrs:{id:"data-driven-tests"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#data-driven-tests"}},[t._v("#")]),t._v(" Data Driven Tests")]),t._v(" "),s("p",[t._v("Execute the same scenario on a different data set.")]),t._v(" "),s("p",[t._v("Let's say you want to test login for different user accounts.\nIn this case, you need to create a datatable and fill it in with credentials.\nThen use "),s("code",[t._v("Data().Scenario")]),t._v(" to include this data and generate multiple scenarios:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Define data table inside a test or load from another module")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" accounts "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DataTable")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//")]),t._v("\naccounts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'123456'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// adding records to a table")]),t._v("\naccounts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("add")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'admin'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'123456'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// You can skip some data. But add them to report as skipped (just like with usual scenarios):")]),t._v("\naccounts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("xadd")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'admin'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'23456'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Pass dataTable to Data()")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Use special param `current` to get current data set")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("accounts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Test Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" current "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Username'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("login"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// current is reserved!")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("password"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Sign In'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Welcome '")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("login"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Also you can set only for Data tests. It will launch executes only the current test but with all data options")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("accounts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("only"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Test Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" current "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Username'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("login"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// current is reserved!")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("password"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Sign In'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Welcome '")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("login"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[s("em",[t._v("Important: you can't use name "),s("code",[t._v("current")]),t._v(" for pageObjects or helpers in data scenarios")])]),t._v(" "),s("p",[t._v("This will produce 2 tests with different data sets.\nCurrent data set is appended to a test name in output:")]),t._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[t._v("✓ Test Login "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"login"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"davert"')]),t._v(","),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"password"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"123456"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n✓ Test Login "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"login"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"admin"')]),t._v(","),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"password"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"123456"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nS Test Login "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"login"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"admin"')]),t._v(","),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"password"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"23456"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// You can filter your data table")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("accounts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("account")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" account"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("login "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("==")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'admin'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Test Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" current "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Username'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("login"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("password"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Sign In'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Welcome '")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" current"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("login"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("This will limit data sets accoring passed function:")]),t._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[t._v("✓ Test Login "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"login"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"admin"')]),t._v(","),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"password"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"123456"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nS Test Login "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"login"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"admin"')]),t._v(","),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"password"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"23456"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Data sets can also be defined with array, generator, or a function.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("*")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("yield")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("yield")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'andrey'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n")])])]),s("p",[s("em",[t._v("HINT: If you don't use DataTable. add "),s("code",[t._v("toString()")]),t._v(" method to each object added to data set, so the data could be pretty printed in a test name")])]),t._v(" "),s("h2",{attrs:{id:"tags"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#tags"}},[t._v("#")]),t._v(" Tags")]),t._v(" "),s("p",[t._v("Append "),s("code",[t._v("@tag")]),t._v(" to your test name, so")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'update user profile @slow'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("Alternativly, use "),s("code",[t._v("tag")]),t._v(" method of Scenario to set additional tags:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'update user profile'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// test goes here")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("tag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@slow'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("tag")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'important'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("All tests with "),s("code",[t._v("@tag")]),t._v(" could be executed with "),s("code",[t._v("--grep '@tag'")]),t._v(" option.")]),t._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[t._v("codeceptjs run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--grep")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@slow'")]),t._v("\n")])])]),s("p",[t._v("Use regex for more flexible filtering:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("--grep '(?=.*@smoke2)(?=.*@smoke3)'")]),t._v(" - run tests with @smoke2 and @smoke3 in name")]),t._v(" "),s("li",[s("code",[t._v('--grep "\\@smoke2|\\@smoke3"')]),t._v(" - run tests with @smoke2 or @smoke3 in name")]),t._v(" "),s("li",[s("code",[t._v("--grep '((?=.*@smoke2)(?=.*@smoke3))|@smoke4'")]),t._v(" - run tests with (@smoke2 and @smoke3) or @smoke4 in name")]),t._v(" "),s("li",[s("code",[t._v("--grep '(?=.*@smoke2)^(?!.*@smoke3)'")]),t._v(" - run tests with @smoke2 but without @smoke3 in name")]),t._v(" "),s("li",[s("code",[t._v("--grep '(?=.*)^(?!.*@smoke4)'")]),t._v(" - run all tests except @smoke4")])]),t._v(" "),s("h2",{attrs:{id:"debug"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#debug"}},[t._v("#")]),t._v(" Debug")]),t._v(" "),s("p",[t._v("CodeceptJS provides a debug mode in which additional information is printed.\nIt can be turned on with "),s("code",[t._v("--debug")]),t._v(" flag.")]),t._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[t._v("npx codeceptjs run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--debug")]),t._v("\n")])])]),s("p",[t._v("to receive even more information turn on "),s("code",[t._v("--verbose")]),t._v(" flag:")]),t._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[t._v("npx codeceptjs run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--verbose")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("You can pause execution and enter "),s("strong",[t._v("interactive console")]),t._v(" mode by calling "),s("code",[t._v("pause()")]),t._v(" inside your test.")])]),t._v(" "),s("p",[t._v("To see a complete internal debug of CodeceptJS use "),s("code",[t._v("DEBUG")]),t._v(" env variable:")]),t._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("DEBUG")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("codeceptjs:* npx codeceptjs run\n")])])]),s("p",[t._v("For an interactive debugging use NodeJS debugger. In "),s("strong",[t._v("WebStorm")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("node")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("$NODE_DEBUG_OPTION")]),t._v(" ./node_modules/.bin/codeceptjs run\n")])])]),s("p",[t._v("For "),s("strong",[t._v("Visual Studio Code")]),t._v(", add the following configuration in launch.json:")]),t._v(" "),s("div",{staticClass:"language-json extra-class"},[s("pre",{pre:!0,attrs:{class:"language-json"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"type"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"node"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"request"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"launch"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"name"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"codeceptjs"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"args"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"run"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"--grep"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"@your_test_tag"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token property"}},[t._v('"program"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"${workspaceFolder}/node_modules/codeceptjs/bin/codecept.js"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"test-options"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#test-options"}},[t._v("#")]),t._v(" Test Options")]),t._v(" "),s("p",[t._v("Features and Scenarios have their options that can be set by passing a hash after their names:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'My feature'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("key")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'My scenario'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("key")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("You can use this options for build your own "),s("a",{attrs:{href:"https://codecept.io/hooks/#plugins",target:"_blank",rel:"noopener noreferrer"}},[t._v("plugins"),s("OutboundLink")],1),t._v(" with "),s("a",{attrs:{href:"https://codecept.io/hooks/#api",target:"_blank",rel:"noopener noreferrer"}},[t._v("event listners"),s("OutboundLink")],1),t._v(". Example:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// for test")]),t._v("\n event"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("dispatcher"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("on")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("event"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("before"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("opts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// or for suite")]),t._v("\n event"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("dispatcher"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("on")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("event"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("suite"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("before"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("suite")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("suite"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("opts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"timeout"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#timeout"}},[t._v("#")]),t._v(" Timeout")]),t._v(" "),s("p",[t._v("Tests can get stuck due to various reasons such as network connection issues, crashed browser, etc.\nThis can make tests process hang. To prevent these situations timeouts can be used. Timeouts can be set explicitly for flaky parts of code, or implicitly in a config.")]),t._v(" "),s("blockquote",[s("p",[t._v("Previous timeout implementation was disabled as it had no effect when dealing with steps and promises.")])]),t._v(" "),s("h3",{attrs:{id:"steps-timeout"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#steps-timeout"}},[t._v("#")]),t._v(" Steps Timeout")]),t._v(" "),s("p",[t._v("It is possible to limit a step execution to specified time with "),s("code",[t._v("I.limitTime")]),t._v(" command.\nIt will set timeout in seconds for the next executed step:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// limit clicking to 5 seconds")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("limitTime")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Link'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("It is possible to set a timeout for all steps implicitly (except waiters) using "),s("RouterLink",{attrs:{to:"/plugins/#steptimeout"}},[t._v("stepTimeout plugin")]),t._v(".")],1),t._v(" "),s("h3",{attrs:{id:"tests-timeout"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#tests-timeout"}},[t._v("#")]),t._v(" Tests Timeout")]),t._v(" "),s("p",[t._v("Test timeout can be set in seconds via Scenario options:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// limit test to 20 seconds")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'slow test that should be stopped'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("timeout")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("This timeout can be set globally in "),s("code",[t._v("codecept.conf.js")]),t._v(" in seconds:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v("exports"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// each test must not run longer than 5 mins")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("timeout")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("300")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"suites-timeout"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#suites-timeout"}},[t._v("#")]),t._v(" Suites Timeout")]),t._v(" "),s("p",[t._v("A timeout for a group of tests can be set on Feature level via options.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// limit all tests in this suite to 30 seconds")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'flaky tests'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("timeout")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("h3",{attrs:{id:"timeout-confguration"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#timeout-confguration"}},[t._v("#")]),t._v(" Timeout Confguration")]),t._v(" "),s("Badge",{attrs:{text:"Updated in 3.4",type:"warning"}}),t._v(" "),s("p",[t._v("Timeout rules can be set globally via config.")]),t._v(" "),s("p",[t._v("To set a timeout for all running tests provide a "),s("strong",[t._v("number of seconds")]),t._v(" to "),s("code",[t._v("timeout")]),t._v(" config option:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside codecept.conf.js or codecept.conf.ts")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("timeout")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// limit all tests in all suites to 30 secs")]),t._v("\n")])])]),s("p",[t._v("It is possible to tune this configuration for a different groups of tests passing options as array and using "),s("code",[t._v("grep")]),t._v(" option to filter tests:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside codecept.conf.js or codecept.conf.ts")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("timeout")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// default timeout is 10secs ")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// but increase timeout for slow tests")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("grep")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@slow'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("50")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("ℹ️ "),s("code",[t._v("grep")]),t._v(" value can be string or regexp")])]),t._v(" "),s("p",[t._v("It is possible to set a timeout for Scenario or Feature:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside codecept.conf.js or codecept.conf.ts")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("timeout")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// timeout for Feature with @slow in title")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("grep")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@slow'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("50")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// timeout for Scenario with 'flaky0' .. `flaky1` in title")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// regexp can be passed to grep")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("grep")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token regex"}},[s("span",{pre:!0,attrs:{class:"token regex-delimiter"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token regex-source language-regex"}},[t._v("flaky[0-9]")]),s("span",{pre:!0,attrs:{class:"token regex-delimiter"}},[t._v("/")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// timeout for all suites")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),s("p",[t._v("Global timeouts will be overridden by explicit timeouts of a test or steps.")]),t._v(" "),s("h3",{attrs:{id:"disable-timeouts"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#disable-timeouts"}},[t._v("#")]),t._v(" Disable Timeouts")]),t._v(" "),s("p",[t._v("To execute tests ignoring all timeout settings use "),s("code",[t._v("--no-timeouts")]),t._v(" option:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run --no-timeouts\n")])])]),s("h2",{attrs:{id:"dynamic-configuration"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#dynamic-configuration"}},[t._v("#")]),t._v(" Dynamic Configuration")]),t._v(" "),s("p",[t._v("Helpers can be reconfigured per scenario or per feature.\nThis might be useful when some tests should be executed with different settings than others.\nIn order to reconfigure tests use "),s("code",[t._v(".config()")]),t._v(" method of "),s("code",[t._v("Scenario")]),t._v(" or "),s("code",[t._v("Feature")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'should be executed in firefox'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// I.amOnPage(..)")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'firefox'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("In this case "),s("code",[t._v("config")]),t._v(" overrides current config of the first helper.\nTo change config of specific helper pass two arguments: helper name and config values:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'should create data via v2 version of API'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// I.amOnPage(..)")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'REST'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("endpoint")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://api.mysite.com/v2'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("Config can also be set by a function, in this case you can get a test object and specify config values based on it.\nThis is very useful when running tests against cloud providers, like BrowserStack. This function can also be asynchronous.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'should report to BrowserStack'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// I.amOnPage(..)")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("desiredCapabilities")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("project")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("suite"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("title"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("title"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Config changes can be applied to all tests in suite:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Admin Panel'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://mysite.com/admin'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Please note that some config changes can't be applied on the fly. For instance, if you set "),s("code",[t._v("restart: false")]),t._v(" in your config and then changing value "),s("code",[t._v("browser")]),t._v(" won't take an effect as browser is already started and won't be closed untill all tests finish.")]),t._v(" "),s("p",[t._v("Configuration changes will be reverted after a test or a suite.")])],1)}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/32.f6446214.js b/assets/js/32.f6446214.js new file mode 100644 index 00000000..61383062 --- /dev/null +++ b/assets/js/32.f6446214.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[32],{334:function(t,s,a){"use strict";a.r(s);var e=a(14),n=Object(e.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"🪄-testing-with-ai"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#🪄-testing-with-ai"}},[t._v("#")]),t._v(" 🪄 Testing with AI")]),t._v(" "),s("p",[s("strong",[t._v("CodeceptJS is the first open-source test automation framework with AI")]),t._v(" features to improve the testing experience. CodeceptJS uses AI provider like OpenAI or Anthropic to auto-heal failing tests, assist in writing tests, and more...")]),t._v(" "),s("p",[t._v("Think of it as your testing co-pilot built into the testing framework")]),t._v(" "),s("blockquote",[s("p",[t._v("🪄 "),s("strong",[t._v("AI features for testing are experimental")]),t._v(". AI works only for web based testing with Playwright, WebDriver, etc. Those features will be improved based on user's experience.")])]),t._v(" "),s("h2",{attrs:{id:"how-ai-improves-automated-testing"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#how-ai-improves-automated-testing"}},[t._v("#")]),t._v(" How AI Improves Automated Testing")]),t._v(" "),s("p",[t._v("LLMs like ChatGPT can technically write automated tests for you. However, ChatGPT misses the context of your application so it will guess elements on page, instead of writing the code that works.")]),t._v(" "),s("p",[t._v("CodeceptJS can share the testing context with AI provider when asked questions about a test.")]),t._v(" "),s("p",[t._v('So, instead of asking "write me a test" it can ask "write a test for '),s("strong",[t._v("this")]),t._v(' page". GPT knows how to write CodeceptJS code, how to build good-looking semantic locators and how to analyze HTML to match them. Even more, GPT suggestions can be tested in real-time in a browser, making a feedback loop.')]),t._v(" "),s("p",[t._v("CodeceptJS AI can do the following:")]),t._v(" "),s("ul",[s("li",[t._v("🏋️‍♀️ "),s("strong",[t._v("assist writing tests")]),t._v(" in "),s("code",[t._v("pause()")]),t._v(" or interactive shell mode")]),t._v(" "),s("li",[t._v("📃 "),s("strong",[t._v("generate page objects")]),t._v(" in "),s("code",[t._v("pause()")]),t._v(" or interactive shell mode")]),t._v(" "),s("li",[t._v("🚑 "),s("strong",[t._v("self-heal failing tests")]),t._v(" (can be used on CI)")]),t._v(" "),s("li",[t._v("💬 send arbitrary prompts to AI provider from any tested page attaching its HTML contents")])]),t._v(" "),s("p",[s("img",{attrs:{src:"/img/fill_form.gif",alt:""}})]),t._v(" "),s("h2",{attrs:{id:"how-it-works"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#how-it-works"}},[t._v("#")]),t._v(" How it works")]),t._v(" "),s("p",[t._v("As we can't send a browser window with ChatGPT we are not be able to fully share the context. But we can chare HTML of the current page, which is quite enough to analyze and identify if a page contains an element which can be used in a test.")]),t._v(" "),s("p",[t._v("AI providers have limits on input tokens but HTML pages can be huge. However, some information from a web page may be irrelevant for testing. For instance, if you test a blog, you won't need text contents of a post, as it can't be used in locators. That's why CodeceptJS sends HTML with "),s("strong",[t._v("all non-interactive HTML elements removed")]),t._v(". So, only links, buttons, fields, etc will be sent to AI as a context. In case you have clickable "),s("code",[t._v("
")]),t._v(" but with no "),s("code",[t._v('role="button"')]),t._v(" it will be ignored. Also, we minify HTML before sending.")]),t._v(" "),s("p",[t._v("Even though, the HTML is still quite big and may exceed the token limit. So we recommend using models with at least 16K input tokens, (approx. 50K of HTML text), which should be enough for most web pages. It is possible to strictly limit the size of HTML to not exceed tokens limit.")]),t._v(" "),s("blockquote",[s("p",[t._v("❗AI features require sending HTML contents to AI provider. Choosing one may depend on the descurity policy of your company. Ask your security department which AI providers you can use.")])]),t._v(" "),s("h2",{attrs:{id:"set-up-ai-provider"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#set-up-ai-provider"}},[t._v("#")]),t._v(" Set up AI Provider")]),t._v(" "),s("p",[t._v("To enable AI features in CodeceptJS you should pick an AI provider and add "),s("code",[t._v("ai")]),t._v(" section to "),s("code",[t._v("codecept.conf")]),t._v(" file. This section should contain "),s("code",[t._v("request")]),t._v(" function which will take a prompt from CodeceptJS, send it to AI provider and return a result.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ai")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("request")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("messages")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// implement OpenAI or any other provider like this")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" ai "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'my-ai-provider'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" ai"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("send")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("messages"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("In "),s("code",[t._v("request")]),t._v(" function "),s("code",[t._v("messages")]),t._v(" is an array of prompt messages in format")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("role")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("content")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'prompt text'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),s("p",[t._v("Which is natively supported by OpenAI, Anthropic, and others. You can adjust messages to expected format before sending a request. The expected response from AI provider is a text in markdown format with code samples, which can be interpreted by CodeceptJS.")]),t._v(" "),s("p",[t._v("Once AI provider is configured run tests with "),s("code",[t._v("--ai")]),t._v(" flag to enable AI features")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run --ai\n")])])]),s("p",[t._v("Below we list sample configuration for popular AI providers")]),t._v(" "),s("h4",{attrs:{id:"openai-gpt"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#openai-gpt"}},[t._v("#")]),t._v(" OpenAI GPT")]),t._v(" "),s("p",[t._v("Prerequisite:")]),t._v(" "),s("ul",[s("li",[t._v("Install "),s("code",[t._v("openai")]),t._v(" package")]),t._v(" "),s("li",[t._v("obtain "),s("code",[t._v("OPENAI_API_KEY")]),t._v(" from OpenAI")]),t._v(" "),s("li",[t._v("set "),s("code",[t._v("OPENAI_API_KEY")]),t._v(" as environment variable")])]),t._v(" "),s("p",[t._v("Sample OpenAI configuration:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ai")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("request")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("messages")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" OpenAI "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'openai'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" openai "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OpenAI")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("apiKey")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" process"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'OPENAI_API_KEY'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" completion "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" openai"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("chat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("completions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("model")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'gpt-3.5-turbo-0125'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n messages"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" completion"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?.")]),t._v("choices"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?.")]),t._v("message"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?.")]),t._v("content"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h4",{attrs:{id:"mixtral"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#mixtral"}},[t._v("#")]),t._v(" Mixtral")]),t._v(" "),s("p",[t._v("Mixtral is opensource and can be used via Cloudflare, Google Cloud, Azure or installed locally.")]),t._v(" "),s("p",[t._v("The simplest way to try Mixtral on your case is using "),s("a",{attrs:{href:"https://groq.com",target:"_blank",rel:"noopener noreferrer"}},[t._v("Groq Cloud"),s("OutboundLink")],1),t._v(" which provides Mixtral access with GPT-like API:")]),t._v(" "),s("p",[t._v("Prerequisite:")]),t._v(" "),s("ul",[s("li",[t._v("Install "),s("code",[t._v("groq-sdk")]),t._v(" package")]),t._v(" "),s("li",[t._v("obtain "),s("code",[t._v("GROQ_API_KEY")]),t._v(" from OpenAI")]),t._v(" "),s("li",[t._v("set "),s("code",[t._v("GROQ_API_KEY")]),t._v(" as environment variable")])]),t._v(" "),s("p",[t._v("Sample Groq configuration with Mixtral model:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ai")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("request")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("messages")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" chatCompletion "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" groq"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("chat"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("completions"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n messages"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("model")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"mixtral-8x7b-32768"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" chatCompletion"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("choices"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?.")]),t._v("message"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?.")]),t._v("content "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("Groq also provides access to other opensource models like llama or gemma")])]),t._v(" "),s("h4",{attrs:{id:"anthropic-claude"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#anthropic-claude"}},[t._v("#")]),t._v(" Anthropic Claude")]),t._v(" "),s("p",[t._v("Prerequisite:")]),t._v(" "),s("ul",[s("li",[t._v("Install "),s("code",[t._v("@anthropic-ai/sdk")]),t._v(" package")]),t._v(" "),s("li",[t._v("obtain "),s("code",[t._v("CLAUDE_API_KEY")]),t._v(" from Anthropic")]),t._v(" "),s("li",[t._v("set "),s("code",[t._v("CLAUDE_API_KEY")]),t._v(" as environment variable")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ai")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("request")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("messages")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" Anthropic "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@anthropic-ai/sdk'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" anthropic "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Anthropic")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("apiKey")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" process"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("CLAUDE_API_KEY")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" resp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" anthropic"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("messages"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("model")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'claude-2.1'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("max_tokens")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1024")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n messages\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" resp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("content"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("c")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("text"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("join")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'\\n\\n'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h4",{attrs:{id:"azure-openai"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#azure-openai"}},[t._v("#")]),t._v(" Azure OpenAI")]),t._v(" "),s("p",[t._v("Prerequisite:")]),t._v(" "),s("ul",[s("li",[t._v("Install "),s("code",[t._v("@azure/openai")]),t._v(" package")]),t._v(" "),s("li",[t._v("obtain "),s("code",[t._v("Azure API key")]),t._v(", "),s("code",[t._v("resource name")]),t._v(" and "),s("code",[t._v("deployment ID")])])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ai")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("request")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("messages")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" OpenAIClient"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" AzureKeyCredential "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"@azure/openai"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" client "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("OpenAIClient")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"https://.openai.azure.com/"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("AzureKeyCredential")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" choices "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" client"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getCompletions")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('""')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" messages"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" choices"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?.")]),t._v("message"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?.")]),t._v("content"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"writing-tests-with-ai-copilot"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#writing-tests-with-ai-copilot"}},[t._v("#")]),t._v(" Writing Tests with AI Copilot")]),t._v(" "),s("p",[t._v("If AI features are enabled when using "),s("RouterLink",{attrs:{to:"/basics/#debug"}},[t._v("interactive pause")]),t._v(" with "),s("code",[t._v("pause()")]),t._v(" command inside tests:")],1),t._v(" "),s("p",[t._v("For instance, let's create a test to try ai features via "),s("code",[t._v("gt")]),t._v(" command:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs gt\n")])])]),s("p",[t._v("Name a test and write the code. We will use "),s("code",[t._v("Scenario.only")]),t._v(" instead of Scenario to execute only this exact test.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'ai'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nScenario"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("only")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'test ai features'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://getbootstrap.com/docs/5.1/examples/checkout/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pause")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Now run the test in debug mode with AI enabled:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run --debug --ai\n")])])]),s("p",[t._v("When pause mode started you can ask GPT to fill in the fields on this page. Use natural language to describe your request, and provide enough details that AI could operate with it. It is important to include at least a space char in your input, otherwise, CodeceptJS will consider the input to be JavaScript code.")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v(" I.fill checkout form with valid values without submitting it\n")])])]),s("p",[s("img",{attrs:{src:"/img/fill_form_1.png",alt:""}})]),t._v(" "),s("p",[t._v("GPT will generate code and data and CodeceptJS will try to execute its code. If it succeeds, the code will be saved to history and you will be able to copy it to your test.")]),t._v(" "),s("p",[s("img",{attrs:{src:"/img/fill_form2.png",alt:""}})]),t._v(" "),s("p",[t._v("This AI copilot works best with long static forms. In the case of complex and dynamic single-page applications, it may not perform as well, as the form may not be present on HTML page yet. For instance, interacting with calendars or inputs with real-time validations (like credit cards) can not yet be performed by AI.")]),t._v(" "),s("p",[t._v("Please keep in mind that GPT can't react to page changes and operates with static text only. This is why it is not ready yet to write the test completely. However, if you are new to CodeceptJS and automated testing AI copilot may help you write tests more efficiently.")]),t._v(" "),s("blockquote",[s("p",[t._v("👶 Enable AI copilot for junior test automation engineers. It may help them to get started with CodeceptJS and to write good semantic locators.")])]),t._v(" "),s("h3",{attrs:{id:"self-healing-tests"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#self-healing-tests"}},[t._v("#")]),t._v(" Self-Healing Tests")]),t._v(" "),s("p",[t._v("In large test suites, the cost of maintaining tests goes exponentially. That's why any effort that can improve the stability of tests pays itself. That's why CodeceptJS has concept of "),s("a",{attrs:{href:"./heal"}},[t._v("heal recipes")]),t._v(", functions that can be executed on a test failure. Those functions can try to revive the test and continue execution. When combined with AI, heal recipe can ask AI provider how to fix the test. It will provide error message, step being executed and HTML context of a page. Based on this information AI can suggest the code to be executed to fix the failing test.")]),t._v(" "),s("p",[t._v("AI healing can solve exactly one problem: if a locator of an element has changed, and an action can't be performed, "),s("strong",[t._v("it matches a new locator, tries a command again, and continues executing a test")]),t._v('. For instance, if the "Sign in" button was renamed to "Login" or changed its class, it will detect a new locator of the button and will retry execution.')]),t._v(" "),s("blockquote",[s("p",[t._v("You can define your own "),s("a",{attrs:{href:"./heal"}},[t._v("heal recipes")]),t._v(" that won't use AI to revive failing tests.")])]),t._v(" "),s("p",[t._v("Heal actions "),s("strong",[t._v("work only on actions like "),s("code",[t._v("click")]),t._v(", "),s("code",[t._v("fillField")])]),t._v(", etc, and won't work on assertions, waiters, grabbers, etc. Assertions can't be guessed by AI, the same way as grabbers, as this may lead to unpredictable results.")]),t._v(" "),s("p",[t._v("If Heal plugin successfully fixes the step, it will print a suggested change at the end of execution. Take it as actionable advice and use it to update the codebase. Heal plugin is supposed to be used on CI, and works automatically without human assistance.")]),t._v(" "),s("p",[t._v("To start, make sure "),s("a",{attrs:{href:"#set-up-ai-provider"}},[t._v("AI provider is connected")]),t._v(", and "),s("a",{attrs:{href:"./heal#how-to-start-healing"}},[t._v("heal recipes were created")]),t._v(" and included into "),s("code",[t._v("codecept.conf.js")]),t._v(" or "),s("code",[t._v("codecept.conf.ts")]),t._v(" config file. Then enable "),s("code",[t._v("heal")]),t._v(" plugin:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("plugins")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("heal")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("enabled")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("If you tests in AI mode and test fails, a request to AI provider will be sent")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run --ai\n")])])]),s("p",[s("img",{attrs:{src:"/img/heal.png",alt:""}})]),t._v(" "),s("p",[t._v("When execution finishes, you will receive information on token usage and code suggestions proposed by AI.\nBy evaluating this information you will be able to check how effective AI can be for your case.")]),t._v(" "),s("h3",{attrs:{id:"arbitrary-gpt-prompts"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#arbitrary-gpt-prompts"}},[t._v("#")]),t._v(" Arbitrary GPT Prompts")]),t._v(" "),s("p",[t._v("What if you want to take AI on the journey of test automation and ask it questions while browsing pages?")]),t._v(" "),s("p",[t._v("This is possible with the new "),s("code",[t._v("AI")]),t._v(" helper. Enable it in your config file in "),s("code",[t._v("helpers")]),t._v(" section:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside codecept.conf")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Playwright, Puppeteer, or WebDrver helper should be enabled too")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Playwright")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("AI")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("AI helper will be automatically attached to Playwright, WebDriver, or another web helper you use. It includes the following methods:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("askGptOnPage")]),t._v(" - sends GPT prompt attaching the HTML of the page. Large pages will be split into chunks, according to "),s("code",[t._v("chunkSize")]),t._v(" config. You will receive responses for all chunks.")]),t._v(" "),s("li",[s("code",[t._v("askGptOnPageFragment")]),t._v(" - sends GPT prompt attaching the HTML of the specific element. This method is recommended over "),s("code",[t._v("askGptOnPage")]),t._v(" as you can reduce the amount of data to be processed.")]),t._v(" "),s("li",[s("code",[t._v("askGptGeneralPrompt")]),t._v(" - sends GPT prompt without HTML.")]),t._v(" "),s("li",[s("code",[t._v("askForPageObject")]),t._v(" - creates PageObject for you, explained in next section.")])]),t._v(" "),s("p",[s("code",[t._v("askGpt")]),t._v(" methods won't remove non-interactive elements, so it is recommended to manually control the size of the sent HTML.")]),t._v(" "),s("p",[t._v("Here are some good use cases for this helper:")]),t._v(" "),s("ul",[s("li",[t._v("get page summaries")]),t._v(" "),s("li",[t._v("inside pause mode navigate through your application and ask to document pages")]),t._v(" "),s("li",[t._v("etc...")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// use it inside test or inside interactive pause")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// pretend you are technical writer asking for documentation")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" pageDoc "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("askGptOnPageFragment")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Act as technical writer, describe what is this page for'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#container'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("As of now, those use cases do not apply to test automation but maybe you can apply them to your testing setup.")]),t._v(" "),s("h2",{attrs:{id:"generate-pageobjects"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#generate-pageobjects"}},[t._v("#")]),t._v(" Generate PageObjects")]),t._v(" "),s("p",[t._v("Last but not the least. AI helper can be used to quickly prototype PageObjects on pages browsed within interactive session.")]),t._v(" "),s("p",[s("img",{attrs:{src:"/img/ai_page_object.png",alt:""}})]),t._v(" "),s("p",[t._v("Enable AI helper as explained in previous section and launch shell:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs shell --ai\n")])])]),s("p",[t._v("Also this is availble from "),s("code",[t._v("pause()")]),t._v(" if AI helper is enabled,")]),t._v(" "),s("p",[t._v("Ensure that browser is started in window mode, then browse the web pages on your site.\nOn a page you want to create PageObject execute "),s("code",[t._v("askForPageObject()")]),t._v(" command. The only required parameter is the name of a page:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("askForPageObject")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("This command sends request to AI provider should create valid CodeceptJS PageObject.\nRun it few times or switch AI provider if response is not satisfactory to you.")]),t._v(" "),s("blockquote",[s("p",[t._v("You can change the style of PageObject and locator preferences by adjusting prompt in a config file")])]),t._v(" "),s("p",[t._v("When completed successfully, page object is saved to "),s("strong",[t._v("output")]),t._v(" directory and loaded into the shell as "),s("code",[t._v("page")]),t._v(" variable so locators and methods can be checked on the fly.")]),t._v(" "),s("p",[t._v("If page object has "),s("code",[t._v("signInButton")]),t._v(" locator you can quickly check it by typing:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("page"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("signInButton"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("If page object has "),s("code",[t._v("clickForgotPassword")]),t._v(" method you can execute it as:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" page"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clickForgotPassword")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("div",{staticClass:"language-shell extra-class"},[s("pre",{pre:!0,attrs:{class:"language-shell"}},[s("code",[t._v("Page object "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" login is saved to "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("..")]),t._v("./output/loginPage-1718579784751.js\nPage object registered "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" this session as "),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("`")]),t._v("page"),s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("`")])]),t._v(" variable\nUse "),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("page.methodName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("`")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" shell to run methods of page object\nUse "),s("span",{pre:!0,attrs:{class:"token variable"}},[s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("`")]),t._v("click"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("page.locatorName"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token variable"}},[t._v("`")])]),t._v(" to check locators of page object\n\n I."),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("page.clickSignUp"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n I.click"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("page.signUpLink"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n I."),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" page.enterPassword"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'asdasd'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n I."),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" page.clickSignIn"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("You can improve prompt by passing custom request as a second parameter:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("askForPageObject")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'implement signIn(username, password) method'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("To generate page object for the part of a page, pass in root locator as third parameter.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("askForPageObject")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#auth'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("In this case, all generated locators, will use "),s("code",[t._v("#auth")]),t._v(" as their root element.")]),t._v(" "),s("p",[t._v("Don't aim for perfect PageObjects but find a good enough one, which you can use for writing your tests.\nAll created page objects are considered temporary, that's why saved to "),s("code",[t._v("output")]),t._v(" directory.")]),t._v(" "),s("p",[t._v("Rename created PageObject to remove timestamp and move it from "),s("code",[t._v("output")]),t._v(" to "),s("code",[t._v("pages")]),t._v(" folder and include it into codecept.conf file:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("include")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("loginPage")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./pages/loginPage.js"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n")])])]),s("h2",{attrs:{id:"advanced-configuration"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#advanced-configuration"}},[t._v("#")]),t._v(" Advanced Configuration")]),t._v(" "),s("p",[t._v("GPT prompts and HTML compression can also be configured inside "),s("code",[t._v("ai")]),t._v(" section of "),s("code",[t._v("codecept.conf")]),t._v(" file:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ai")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// define how requests to AI are sent ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("request")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("messages")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// redefine prompts ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("prompts")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// {}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// how to process HTML content")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("html")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// {}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// limit the number of tokens to be")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// used during one session")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("maxTokens")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100000")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Default prompts for healing steps or writing steps can be re-declared. Use function that accepts HTML as the first parameter and additional information as second and create a prompt from that information. Prompt should be an array of messages with "),s("code",[t._v("role")]),t._v(" and "),s("code",[t._v("content")]),t._v(" data set.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ai")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("prompts")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("writeStep")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("html"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" input")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("role")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("content")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'As a test engineer...'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("healStep")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("html"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" step"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" error"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" prevSteps "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("role")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("content")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'As a test engineer...'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("generatePageObject")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("html"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" extraPrompt "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" rootLocator "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("role")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("content")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'As a test engineer...'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("HTML is processed before sending it to GPT to reduce the number of tokens used. You may need to adjust default settings to work with your application. For instance, the default strategy may remove some important elements, or contrary keep HTML elements that have no use for test automation.")]),t._v(" "),s("p",[t._v("Here is the default config:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ai")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("html")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("maxLength")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("50000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("simplify")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("minify")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("interactiveElements")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'a'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'input'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'button'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'select'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'textarea'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'option'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("textElements")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'label'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'h1'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'h2'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("allowedAttrs")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'id'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'for'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'class'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'name'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'type'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'value'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'tabindex'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'aria-labelledby'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'aria-label'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'label'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'placeholder'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'title'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'alt'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'src'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'role'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("allowedRoles")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'button'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'checkbox'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'search'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'textbox'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'tab'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ul",[s("li",[s("code",[t._v("maxLength")]),t._v(": the size of HTML to cut to not reach the token limit. 50K is the current default but you may try to increase it or even set it to null.")]),t._v(" "),s("li",[s("code",[t._v("simplify")]),t._v(": should we process HTML before sending to GPT. This will remove all non-interactive elements from HTML.")]),t._v(" "),s("li",[s("code",[t._v("minify")]),t._v(": shold HTML be additionally minified. This removed empty attributes, shortens notations, etc.")]),t._v(" "),s("li",[s("code",[t._v("interactiveElements")]),t._v(": explicit list of all elements that are considered interactive.")]),t._v(" "),s("li",[s("code",[t._v("textElements")]),t._v(": elements that contain text which can be used for test automation.")]),t._v(" "),s("li",[s("code",[t._v("allowedAttrs")]),t._v(": explicit list of attributes that may be used to construct locators. If you use special "),s("code",[t._v("data-")]),t._v(" attributes to enable locators, add them to the list.")]),t._v(" "),s("li",[s("code",[t._v("allowedRoles")]),t._v(": list of roles that make standard elements interactive.")])]),t._v(" "),s("p",[t._v("It is recommended to try HTML processing on one of your web pages before launching AI features of CodeceptJS.")]),t._v(" "),s("p",[t._v("To do that open the common page of your application and using DevTools copy the outerHTML of "),s("code",[t._v("")]),t._v(" element. Don't use "),s("code",[t._v("Page Source")]),t._v(" for that, as it may not include dynamically added HTML elements. Save this HTML into a file and create a NodeJS script:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" removeNonInteractiveElements "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'codeceptjs/lib/html'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" fs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'fs'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" htmlOpts "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("interactiveElements")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'a'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'input'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'button'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'select'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'textarea'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'label'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'option'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("allowedAttrs")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'id'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'for'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'class'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'name'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'type'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'value'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'aria-labelledby'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'aria-label'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'label'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'placeholder'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'title'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'alt'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'src'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'role'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("textElements")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'label'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'h1'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'h2'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("allowedRoles")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'button'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'checkbox'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'search'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'textbox'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'tab'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nhtml "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" fs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("readFileSync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'saved.html'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'utf8'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" result "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("removeNonInteractiveElements")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("html"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" htmlOpts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nconsole"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Tune the options until you are satisfied with the results and use this as "),s("code",[t._v("html")]),t._v(" config for "),s("code",[t._v("ai")]),t._v(" section inside "),s("code",[t._v("codecept.conf")]),t._v(" file.\nIt is also recommended to check the source of "),s("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/blob/3.x/lib/html.js",target:"_blank",rel:"noopener noreferrer"}},[t._v("removeNonInteractiveElements"),s("OutboundLink")],1),t._v(" and if needed propose improvements to it.")]),t._v(" "),s("p",[t._v("For instance, if you use "),s("code",[t._v("data-qa")]),t._v(" attributes to specify locators and you want to include them in HTML, use the following config:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside codecept.conf.js")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ai")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("html")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("allowedAttrs")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'data-qa'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'id'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'for'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'class'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'name'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'type'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'value'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'aria-labelledby'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'aria-label'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'label'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'placeholder'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'title'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'alt'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'src'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'role'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"debugging"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#debugging"}},[t._v("#")]),t._v(" Debugging")]),t._v(" "),s("p",[t._v("To debug AI features run tests with "),s("code",[t._v('DEBUG="codeceptjs:ai"')]),t._v(" flag. This will print all prompts and responses from AI provider")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v('DEBUG="codeceptjs:ai" npx codeceptjs run --ai\n')])])]),s("p",[t._v("or if you run it in shell mode:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v('DEBUG="codeceptjs:ai" npx codeceptjs shell --ai\n')])])])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/33.5dfd09f2.js b/assets/js/33.5dfd09f2.js new file mode 100644 index 00000000..d5c8f10a --- /dev/null +++ b/assets/js/33.5dfd09f2.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[33],{335:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"protractor-testing-with-codeceptjs"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#protractor-testing-with-codeceptjs"}},[t._v("#")]),t._v(" Protractor Testing with CodeceptJS")]),t._v(" "),s("h2",{attrs:{id:"introduction"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#introduction"}},[t._v("#")]),t._v(" Introduction")]),t._v(" "),s("p",[t._v("CodeceptJS is an acceptance testing framework. In the diversified world of JavaScript testing libraries, it aims to create a unified high-level API for end-to-end testing, powered by a variety of backends.\nCodeceptJS allows you to write a test and switch the execution driver via config: whether it's "),s("em",[t._v("wedriverio")]),t._v(", "),s("em",[t._v("puppeteer")]),t._v(", or "),s("em",[t._v("protractor")]),t._v(" depends on you.\nThis way you aren't bound to a specific implementation, and your acceptance tests will work no matter what framework is running them.")]),t._v(" "),s("p",[s("a",{attrs:{href:"http://www.protractortest.org/#/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Protractor"),s("OutboundLink")],1),t._v(" is an official tool for testing AngularJS applications.\nCodeceptJS should not be considered as alternative to Protractor, but rather a testing framework that leverages this powerful library.")]),t._v(" "),s("p",[s("img",{attrs:{src:"/img/angular-protractor.png",alt:"angular-protractor"}})]),t._v(" "),s("p",[t._v("There is no magic in testing of AngularJS application in CodeceptJS.\nYou just execute regular Protractor commands, packaged into a simple, high-level API.")]),t._v(" "),s("p",[s("img",{attrs:{src:"/img/todo.png",alt:"todo-mvc"}})]),t._v(" "),s("p",[t._v("As an example, we will use the popular "),s("a",{attrs:{href:"http://todomvc.com/examples/angularjs/#/",target:"_blank",rel:"noopener noreferrer"}},[t._v("TodoMVC application"),s("OutboundLink")],1),t._v(".\nHow would we test creating a new todo item using CodeceptJS?")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'create todo item'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#todo-count'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("model")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'newTodo'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Write a guide'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pressKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Enter'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Write a guide'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("repeater")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"todo in todos"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1 item left'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#todo-count'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("A similar test written using Protractor's native syntax (inherited from selenium-webdriver) would look like this:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("it")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'should create todo item'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n browser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://todomvc.com/examples/angularjs/#/"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("element")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("by"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("css")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"#todo-count"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("isPresent")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toBeFalsy")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" inputField "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("element")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("by"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("model")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"newTodo"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n inputField"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendKeys")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Write a guide"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n inputField"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendKeys")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("protractor"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ENTER")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" todos "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" element"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("all")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("by"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("repeater")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"todo in todos"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("todos"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("last")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getText")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toEqual")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Write a guide"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("element")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("by"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("css")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"#todo-count"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getText")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toContain")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1 items left'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Compared to the API proposed by CodeceptJS, the Protractor code looks more complicated.\nEven more important, it's harder to read and follow the logic of the Protractor test.\nReadability is a crucial part of acceptance testing.\nTests should be easy to modify when there are changes in the specification or design.\nIf the test is written in Protractor, it would likely require someone familiar with Protractor to make the change, whereas CodeceptJS allows anyone to understand and modify the test.\nCodeceptJS provides scenario-driven approach, so a test is just a step-by-step representation of real user actions.\nThis means you can easily read and understand the steps in a test scenario, and edit the steps when the test needs to be changed.")]),t._v(" "),s("p",[t._v("In this way, CodeceptJS is similar to Cucumber. If you run a test with "),s("code",[t._v("--steps")]),t._v(" option you will see this output:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("TodoMvc --\n create todo item\n • I am on page "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/"')]),t._v("\n • I dont see element "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"#todo-count"')]),t._v("\n • I fill field "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"model"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"newTodo"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(", "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Write a guide"')]),t._v("\n • I press key "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Enter"')]),t._v("\n • I see "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Write a guide"')]),t._v(", "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"repeater"')]),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(":")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"todo in todos"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n • I see "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"1 item left"')]),t._v(", "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"#todo-count"')]),t._v("\n ✓ OK "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" 968ms\n")])])]),s("p",[t._v("Unlike Cucumber, CodeceptJS is not about writing test scenarios to satisfy business rules or requirements.\nInstead, its "),s("strong",[t._v("goal is to provide standard action steps you can use for testing applications")]),t._v(".\nAlthough it can't cover 100% of use cases, CodeceptJS aims for 90%. For the remainder, you can write your own steps inside a "),s("a",{attrs:{href:"http://codecept.io/helpers/",target:"_blank",rel:"noopener noreferrer"}},[t._v("custom Helper"),s("OutboundLink")],1),t._v(" using Protractor's API.")]),t._v(" "),s("h3",{attrs:{id:"setting-up-codeceptjs-with-protractor"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#setting-up-codeceptjs-with-protractor"}},[t._v("#")]),t._v(" Setting up CodeceptJS with Protractor")]),t._v(" "),s("p",[t._v("To start using CodeceptJS you will need to install it via NPM and initialize it in a directory with tests.")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("npm")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" codeceptjs "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--save")]),t._v("\nnpx codeceptjs init\n")])])]),s("p",[t._v("You will be asked questions about the initial configuration, make sure you select the Protractor helper.\nIf your project didn't already have the Protractor library, it "),s("strong",[t._v("will be installed")]),t._v(" as part of this process.\nPlease agree to extend steps, and use "),s("code",[t._v("http://todomvc.com/examples/angularjs/")]),t._v(" as the url for Protractor helper.")]),t._v(" "),s("p",[t._v("For TodoMVC application, you will have following config created in the "),s("code",[t._v("codecept.conf.js")]),t._v(" file:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v("exports"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("tests")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./*_test.js'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("timeout")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("output")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./output'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Protractor")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'http://todomvc.com/examples/angularjs/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("driver")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'hosted'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'chrome'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("rootElement")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'body'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("include")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./steps_file.js'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("bootstrap")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("mocha")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'todoangular'")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Your first test can be generated with the "),s("code",[t._v("gt")]),t._v(" command:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("npx codeceptjs gt\n")])])]),s("p",[t._v("After that, you can start writing your first CodeceptJS/Angular tests.\nPlease refer to the "),s("a",{attrs:{href:"http://codecept.io/helpers/Protractor/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Protractor helper"),s("OutboundLink")],1),t._v(" documentation for a list of all available actions.\nYou can also run the "),s("code",[t._v("list")]),t._v(" command to see methods of I:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("npx codeceptjs list\n")])])]),s("h2",{attrs:{id:"starting-selenium-server"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#starting-selenium-server"}},[t._v("#")]),t._v(" Starting Selenium Server")]),t._v(" "),s("p",[t._v("Protractor requires Selenium Server to be started and running. To start and stop Selenium automatically install "),s("code",[t._v("@wdio/selenium-standalone-service")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npm i @wdio/selenium-standalone-service --save\n")])])]),s("p",[t._v("Enable it in the "),s("code",[t._v("codecept.conf.js")]),t._v(" file, inside the plugins section:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v("exports"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside codecept.conf.js")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("plugins")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("wdio")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("enabled")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("services")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'selenium-standalone'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"testing-non-angular-applications"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#testing-non-angular-applications"}},[t._v("#")]),t._v(" Testing non-Angular Applications")]),t._v(" "),s("p",[t._v("Protractor can also be used to test applications built without AngularJS. In this case, you need to disable the angular synchronization feature inside the config:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Protractor")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://todomvc.com/examples/angularjs/"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("driver")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"hosted"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"firefox"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("angular")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"writing-your-first-test"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#writing-your-first-test"}},[t._v("#")]),t._v(" Writing Your First Test")]),t._v(" "),s("p",[t._v("Your test scenario should always use the "),s("code",[t._v("I")]),t._v(" object to execute commands.\nThis is important, as all methods of "),s("code",[t._v("I")]),t._v(" are running in the global promise chain. This way, CodeceptJS makes sure everything is executed in right order.\nTo start with opening a webpage, use the "),s("code",[t._v("amOnPage")]),t._v(" command for. Since we already specified the full URL to the TodoMVC app, we can pass the relative path for our url, instead of the absolute url:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Todo MVC'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'create todo item'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("All scenarios should describe actions on the site, with assertions at the end. In CodeceptJS, assertion commands have the "),s("code",[t._v("see")]),t._v(" or "),s("code",[t._v("dontSee")]),t._v(" prefix:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Todo MVC'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'create todo item'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#todo-count'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("A test can be executed with the "),s("code",[t._v("run")]),t._v(" command, we recommend using the "),s("code",[t._v("--steps")]),t._v(" option to print out the step-by-step execution:")]),t._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[t._v("npx codeceptjs run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--steps")]),t._v("\n")])])]),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v('Test root is assumed to be /home/davert/demos/todoangular\nUsing the selenium server at http://localhost:4444/wd/hub\n\nTodoMvc --\n create todo item\n • I am on page "/"\n • I dont see element "#todo-count"\n')])])]),s("h2",{attrs:{id:"running-several-scenarios"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#running-several-scenarios"}},[t._v("#")]),t._v(" Running Several Scenarios")]),t._v(" "),s("p",[t._v("By now, you should have a test similar to the one shown in the beginning of this guide. We probably want to have multiple tests though, like testing the editing of todo items, checking todo items, etc.")]),t._v(" "),s("p",[t._v("Let's prepare our test to contain multiple scenarios. All of our test scenarios will need to to start with with the main page of application open, so "),s("code",[t._v("amOnPage")]),t._v(" can be moved into the "),s("code",[t._v("Before")]),t._v(" hook:\nOur scenarios will also probably deal with created todo items, so we can move the logic of creating a new todo into a function.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'TodoMvc'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Before")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("createTodo")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("model")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'newTodo'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pressKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Enter'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'create todo item'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#todo-count'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createTodo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Write a guide'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Write a guide'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("repeater")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"todo in todos"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1 item left'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#todo-count'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("and now we can add even more tests!")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'edit todo'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createTodo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'write a review'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'write a review'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("repeater")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"todo in todos"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("doubleClick")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'write a review'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pressKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Control'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'a'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pressKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'write old review'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pressKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Enter'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'write old review'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("repeater")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"todo in todos"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'check todo item'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createTodo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'my new item'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1 item left'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#todo-count'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("checkOption")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("model")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'todo.completed'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'0 items left'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#todo-count'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("This example is "),s("a",{attrs:{href:"https://github.com/DavertMik/codeceptjs-angular-todomvc",target:"_blank",rel:"noopener noreferrer"}},[t._v("available on GitHub"),s("OutboundLink")],1),t._v(".")])]),t._v(" "),s("h2",{attrs:{id:"locators"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#locators"}},[t._v("#")]),t._v(" Locators")]),t._v(" "),s("p",[t._v("You may have noticed that CodeceptJS doesn't use "),s("code",[t._v("by.*")]),t._v(" locators which are common in Protractor or Selenium Webdriver.\nInstead, most methods expect you to pass valid CSS selectors or XPath. If you don't want CodeceptJS to guess the locator type, then you can specify the type using "),s("em",[t._v("strict locators")]),t._v(". This is the CodeceptJS version of "),s("code",[t._v("by")]),t._v(", so you can also reuse your angular specific locators (like models, repeaters, bindings, etc):")]),t._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("css: "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'button'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("repeater: "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"todo in todos"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("binding: "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'latest'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("When dealing with clicks, we can specify a text value. CodeceptJS will use that value to search the web page for a valid clickable element containing our specified text.\nThis enables us to search for links and buttons by their text.")]),t._v(" "),s("p",[t._v("The same is true for form fields: they can be searched by field name, label, and so on.")]),t._v(" "),s("p",[t._v("Using smart locators makes tests easier to write, however searching an element by text is slower than searching via CSS|XPath, and is much slower than using strict locators.")]),t._v(" "),s("h2",{attrs:{id:"refactoring"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#refactoring"}},[t._v("#")]),t._v(" Refactoring")]),t._v(" "),s("p",[t._v("In the previous examples, we moved actions into the "),s("code",[t._v("createTodo")]),t._v(" function. Is there a more elegant way of refactoring?\nCan we instead write a function like "),s("code",[t._v("I.createTodo()")]),t._v(" which we can reuse? In fact, we can do so by editing the "),s("code",[t._v("steps_file.js")]),t._v(" file created by the init command.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// in this file you can append custom step methods to 'I' object")]),t._v("\n\nmodule"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("exports")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("actor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("createTodo")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("title")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("model")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'newTodo'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" title"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pressKey")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Enter'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("That's it, our method is now available to use as "),s("code",[t._v("I.createTodo(title)")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'create todo item'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#todo-count'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("createTodo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Write a guide'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Write a guide'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("repeater")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"todo in todos"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1 item left'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#todo-count'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("To learn more about refactoring options in CodeceptJS read "),s("a",{attrs:{href:"http://codecept.io/pageobjects/",target:"_blank",rel:"noopener noreferrer"}},[t._v("PageObjects guide"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"extending"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#extending"}},[t._v("#")]),t._v(" Extending")]),t._v(" "),s("p",[t._v("What if CodeceptJS doesn't provide some specific Protractor functionality you need? If you don't know how to do something with CodeceptJS, you can simply revert back to using Protractor syntax!")]),t._v(" "),s("p",[t._v("Create a custom helper, define methods for it, and use it inside the I object. Your Helper can access "),s("code",[t._v("browser")]),t._v(" from Protractor\nby accessing the Protractor helper:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" browser "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helpers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Protractor'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("browser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("or use global "),s("code",[t._v("element")]),t._v(" and "),s("code",[t._v("by")]),t._v(" variables to locate elements:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v("element"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("all")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("by"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("repeater")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'result in memory'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("This is the recommended way to implement all custom logic using low-level Protractor syntax in order to reuse it inside of test scenarios.\nFor more information, see an "),s("a",{attrs:{href:"http://codecept.io/helpers/#protractor-example",target:"_blank",rel:"noopener noreferrer"}},[t._v("example of such a helper"),s("OutboundLink")],1),t._v(".")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/34.305c1a4b.js b/assets/js/34.305c1a4b.js new file mode 100644 index 00000000..9db0fd8a --- /dev/null +++ b/assets/js/34.305c1a4b.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[34],{340:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"api-testing"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#api-testing"}},[t._v("#")]),t._v(" API Testing")]),t._v(" "),s("p",[t._v("CodeceptJS provides a way to write tests in declarative manner for REST and GraphQL APIs.")]),t._v(" "),s("p",[t._v("Take a look:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendGetRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/users/1'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// returns { "user": { "name": "jon" }, "projects": [] }')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseCodeIsSuccessful")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseContainsKeys")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'projects'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseContainsJson")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'jon'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseMatchesJsonSchema")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("$")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" $"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("object")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" $"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("object")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" $"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("projects")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" $"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("array")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("In this code we checked API request for:")]),t._v(" "),s("ul",[s("li",[t._v("status code")]),t._v(" "),s("li",[t._v("data inclusion")]),t._v(" "),s("li",[t._v("data structure")])]),t._v(" "),s("p",[t._v("These are the things you should generally test your APIs for.")]),t._v(" "),s("blockquote",[s("p",[t._v("🤓 It is recommended to check only invariable parts of responses. Check for required fields and only values you control. For instance, it is not recommended to check id fields, date fields, as they can be frequently changed.")])]),t._v(" "),s("h2",{attrs:{id:"installation"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#installation"}},[t._v("#")]),t._v(" Installation")]),t._v(" "),s("p",[t._v("Install CodeceptJS if it is not installed yet.")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npm i codeceptjs --save-dev\n")])])]),s("p",[t._v("Initialize CodeceptJS and select REST or GraphQL helper when asked for a helper:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs init\n")])])]),s("h2",{attrs:{id:"configuration"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#configuration"}},[t._v("#")]),t._v(" Configuration")]),t._v(" "),s("p",[t._v("Ensure that inside "),s("code",[t._v("codecept.conf.js")]),t._v(" in helpers section "),s("code",[t._v("REST")]),t._v(" or "),s("code",[t._v("GraphQL")]),t._v(" helpers are enabled.")]),t._v(" "),s("ul",[s("li",[t._v("If you use "),s("code",[t._v("REST")]),t._v(" helper add "),s("code",[t._v("JSONResponse")]),t._v(" helper below with no extra config:")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside codecept.conf.js")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REST")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("endpoint")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'http://localhost:3000/api'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// .. add JSONResponse helper here")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("JSONResponse")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ul",[s("li",[t._v("If you use "),s("code",[t._v("GraphQL")]),t._v(" helper add "),s("code",[t._v("JSONResponse")]),t._v(" helper, configuring it to use GraphQL for requests:")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("GraphQL")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("endpoint")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'http://localhost:3000/graphql'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// .. add JSONResponse helper here")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("JSONResponse")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("requestHelper")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'GraphQL'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Originally, REST and GraphQL helpers were not designed for API testing.\nThey were used to perform API requests for browser tests. As so, they lack assertion methods to API responses.")]),t._v(" "),s("p",[s("RouterLink",{attrs:{to:"/helpers/JSONResponse/"}},[s("code",[t._v("JSONResponse")])]),t._v(" helper adds response assertions.")],1),t._v(" "),s("blockquote",[s("p",[t._v("💡 In CodeceptJS assertions start with "),s("code",[t._v("see")]),t._v(" prefix. Learn more about assertions by "),s("RouterLink",{attrs:{to:"/helpers/JSONResponse/"}},[t._v("opening reference for JSONResponse")]),t._v(" helper.")],1)]),t._v(" "),s("p",[t._v("Generate TypeScript definitions to get auto-completions for JSONResponse:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs def\n")])])]),s("p",[t._v("After helpers were configured and typings were generated, you can start writing first API test. By default, CodeceptJS saves tests in "),s("code",[t._v("tests")]),t._v(" directory and uses "),s("code",[t._v("*_test.js")]),t._v(" suffix. The "),s("code",[t._v("init")]),t._v(" command created the first test for you to start.")]),t._v(" "),s("blockquote",[s("p",[t._v("Check "),s("a",{attrs:{href:"https://github.com/codeceptjs/api-examples",target:"_blank",rel:"noopener noreferrer"}},[t._v("API Examples"),s("OutboundLink")],1),t._v(" to see tests implementations.")])]),t._v(" "),s("h2",{attrs:{id:"requests"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#requests"}},[t._v("#")]),t._v(" Requests")]),t._v(" "),s("p",[s("RouterLink",{attrs:{to:"/helpers/REST/"}},[t._v("REST")]),t._v(" or "),s("RouterLink",{attrs:{to:"/helpers/GraphQL/"}},[t._v("GraphQL")]),t._v(" helpers implement methods for making API requests.\nBoth helpers send requests via HTTP protocol from CodeceptJS process.\nFor most cases, you will need to have authentication. It can be passed via headers, which can be added to helper's configuration in "),s("code",[t._v("codecept.conf.js")]),t._v(".")],1),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REST")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("defaultHeaders")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// use Bearer Authorization")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Authorization'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Bearer 11111'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Content-Type'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'application/json'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Accept'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'application/json'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Or you can use the browser cookies if you are running browser session.\nIn this case use "),s("code",[t._v("setSharedCookies()")]),t._v(" from "),s("code",[t._v("@codeceptjs/configure")]),t._v(" package:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" setSharedCookies "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@codeceptjs/configure'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// add this before exports.config")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setSharedCookies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nexports"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// also works with Playwright or Puppeteer")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//... ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REST")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"rest"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#rest"}},[t._v("#")]),t._v(" REST")]),t._v(" "),s("p",[t._v("REST helper can send GET/POST/PATCH/etc requests to REST API endpoint:")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"/helpers/REST#sendGetRequest"}},[s("code",[t._v("I.sendGetRequest()")])])]),t._v(" "),s("li",[s("a",{attrs:{href:"/helpers/REST#sendPostRequest"}},[s("code",[t._v("I.sendPostRequest()")])])]),t._v(" "),s("li",[s("a",{attrs:{href:"/helpers/REST#sendPutRequest"}},[s("code",[t._v("I.sendPutRequest()")])])]),t._v(" "),s("li",[s("a",{attrs:{href:"/helpers/REST#sendPatchRequest"}},[s("code",[t._v("I.sendPatchRequest()")])])]),t._v(" "),s("li",[s("a",{attrs:{href:"/helpers/REST#sendDeleteRequest"}},[s("code",[t._v("I.sendDeleteRequest()")])])]),t._v(" "),s("li",[t._v("...")])]),t._v(" "),s("p",[t._v("Authentication headers can be set in "),s("a",{attrs:{href:"https://codecept.io/helpers/REST/#configuration",target:"_blank",rel:"noopener noreferrer"}},[t._v("helper's config"),s("OutboundLink")],1),t._v(" or per test with headers or special methods like "),s("code",[t._v("I.amBearerAuthenticated")]),t._v(".")]),t._v(" "),s("p",[t._v("Example:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Users endpoint'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'create user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// this way we pass Bearer token")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amBearerAuthenticated")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("secret")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'token-is-here'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// for custom authorization with headers use")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// I.haveRequestHeaders method")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// here we send a POST request")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendPostRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/users'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'joe'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("email")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'joe@mail.com'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// usually we won't need direct access to response object for API testing ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// but you can obtain it from request")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// check the last request was successful")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// this method introduced by JSONResponse helper")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseCodeIsSuccessful")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("h3",{attrs:{id:"graphql"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#graphql"}},[t._v("#")]),t._v(" GraphQL")]),t._v(" "),s("p",[t._v("GraphQL have request format different then in REST API, but the response format is the same.\nIt's plain old JSON. This why "),s("code",[t._v("JSONResponse")]),t._v(" helper works for both API types.\nConfigure authorization headers in "),s("code",[t._v("codecept.conf.js")]),t._v(" and make your first query:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Users endpoint'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'get user by query'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// make GraphQL query or mutation")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" resp "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendQuery")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'{ user(id: 0) { id name email }}'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseCodeIsSuccessful")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// GraphQL always returns key data as part of response")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseContainsKeys")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'data'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// check data for partial inclusion")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseContainsJson")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("data")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john doe'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("email")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'johnd@mutex.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("GraphQL helper has two methods available:")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"/helpers/GraphQL#sendQuery"}},[s("code",[t._v("I.sendQuery()")])])]),t._v(" "),s("li",[s("a",{attrs:{href:"/helpers/GraphQL#sendMutation"}},[s("code",[t._v("I.sendMutation()")])])])]),t._v(" "),s("h2",{attrs:{id:"assertions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#assertions"}},[t._v("#")]),t._v(" Assertions")]),t._v(" "),s("p",[s("code",[t._v("JSONResponse")]),t._v(" provides set of assertions for responses in JSON format. These assertions were designed to check only invariable parts of responses. So instead of checking that response equals to the one provided, we will check for data inclusion and structure matching.")]),t._v(" "),s("p",[t._v("For most of cases, you won't need to perform assertions by accessing "),s("code",[t._v("response")]),t._v(" object directly. All assretions are performed under hood inside "),s("code",[t._v("JSONResponse")]),t._v(" module. It is recommended to keep it that way, to keep tests readable and make test log to contain all assertions.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I make API call'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// request was made by REST ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// or by GraphQL helper")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// check that response code is 2xx")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseCodeIsSuccessful")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// check that response contains keys")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseContainsKeys")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'data'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'pages'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'meta'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"response-status-codes"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#response-status-codes"}},[t._v("#")]),t._v(" Response Status Codes")]),t._v(" "),s("p",[s("a",{attrs:{href:"https://developer.mozilla.org/en-US/docs/Web/HTTP/Status",target:"_blank",rel:"noopener noreferrer"}},[t._v("Response status codes"),s("OutboundLink")],1),t._v(" can be checked to be equal to some value or to be in a specific range.\nTo check that response code is "),s("code",[t._v("200")]),t._v(" call "),s("code",[t._v("I.seeResponseCodeIs")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseCodeIs")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("But because other response codes in 2xx range are also valid responses, you can use "),s("code",[t._v("seeResponseCodeIsSuccessful()")]),t._v(" which will match 200 (OK), 201 (Created), 206 (Partial Content) and others. Methods to check 3xx, 4xx, 5xx response statuses also available.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// matches 200, 201, 202, ... 206")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseCodeIsSuccessful")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// matches 300...308")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseCodeIsRedirection")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// matches 400..451")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseCodeIsClientError")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// matches 500-511")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseCodeIsServerError")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"structure"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#structure"}},[t._v("#")]),t._v(" Structure")]),t._v(" "),s("p",[t._v("The most basic thing to check in response is existence of keys in JSON object. Use "),s("a",{attrs:{href:"/helpers/JSONResponse#seeResponseContainsKeys"}},[s("code",[t._v("I.seeResponseContainsKeys()")])]),t._v(" method for it:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// response is { "name": "joe", "email": "joe@joe.com" }')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseContainsKeys")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'name'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'email'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("ℹ️ If response is an array, it will check that every element in array have provided keys")])]),t._v(" "),s("p",[t._v("However, this is a very naive approach. It won't work for arrays or nested objects.\nTo check complex JSON structures "),s("code",[t._v("JSONResponse")]),t._v(" helper uses "),s("a",{attrs:{href:"https://joi.dev",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("joi")]),s("OutboundLink")],1),t._v(" library.\nIt has rich API to validate JSON by the schema defined using JavaScript.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// require joi library, ")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// it is installed with CodeceptJS")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" Joi "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'joi'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create schema definition using Joi API")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" schema "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" Joi"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("object")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("keys")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("email")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Joi"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("email")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("required")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("phone")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Joi"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("string")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("regex")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token regex"}},[s("span",{pre:!0,attrs:{class:"token regex-delimiter"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token regex-source language-regex"}},[t._v("^\\d{3}-\\d{3}-\\d{4}$")]),s("span",{pre:!0,attrs:{class:"token regex-delimiter"}},[t._v("/")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("required")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("birthday")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Joi"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("date")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("max")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1-1-2004'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("iso")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// check that response matches that schema")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseMatchesJsonSchema")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("schema"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"data-inclusion"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#data-inclusion"}},[t._v("#")]),t._v(" Data Inclusion")]),t._v(" "),s("p",[t._v("To check that response contains expected data use "),s("code",[t._v("I.seeResponseContainsJson")]),t._v(" method.\nIt will check the response data for partial match.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseContainsJson")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("email")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user@user.com'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("ℹ️ If response is an array, it will check that at least one element in array matches JSON")])]),t._v(" "),s("p",[t._v("To perform arbitrary assertions on a response object use "),s("code",[t._v("seeResponseValidByCallback")]),t._v(".\nIt allows you to do any kind of assertions by using "),s("code",[t._v("expect")]),t._v(" from "),s("a",{attrs:{href:"https://www.chaijs.com",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("chai")]),s("OutboundLink")],1),t._v(" library.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseValidByCallback")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" status"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" expect "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// we receive data and expect to combine them for good assertion")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("users"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("to"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("be"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("gte")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("h2",{attrs:{id:"extending-jsonresponse"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#extending-jsonresponse"}},[t._v("#")]),t._v(" Extending JSONResponse")]),t._v(" "),s("p",[t._v("To add more assertions it is recommended to create a custom helper.\nInside it you can get access to latest JSON response:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside a custom helper")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("makeSomeCustomAssertion")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helpers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("JSONResponse"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("response"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/35.dfdb7060.js b/assets/js/35.dfdb7060.js new file mode 100644 index 00000000..f2e8501c --- /dev/null +++ b/assets/js/35.dfdb7060.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[35],{385:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"getting-started"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#getting-started"}},[t._v("#")]),t._v(" Getting Started")]),t._v(" "),s("p",[t._v("CodeceptJS is a modern end to end testing framework with a special BDD-style syntax. The tests are written as a linear scenario of the user's action on a site.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'CodeceptJS demo'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'check Welcome page on site'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Welcome'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Tests are expected to be written in "),s("strong",[t._v("ECMAScript 7")]),t._v(".")]),t._v(" "),s("p",[t._v("Each test is described inside a "),s("code",[t._v("Scenario")]),t._v(" function with the "),s("code",[t._v("I")]),t._v(" object passed into it.\nThe "),s("code",[t._v("I")]),t._v(" object is an "),s("strong",[t._v("actor")]),t._v(", an abstraction for a testing user. The "),s("code",[t._v("I")]),t._v(" is a proxy object for currently enabled "),s("strong",[t._v("Helpers")]),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"architecture"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#architecture"}},[t._v("#")]),t._v(" Architecture")]),t._v(" "),s("p",[t._v("CodeceptJS bypasses execution commands to helpers. Depending on the helper enabled, your tests will be executed differently.")]),t._v(" "),s("p",[t._v("The following is a diagram of the CodeceptJS architecture:")]),t._v(" "),s("p",[s("img",{attrs:{src:"/img/architecture.png",alt:"architecture"}})]),t._v(" "),s("p",[t._v("All helpers share the same API, so it's easy to migrate tests from one backend to another.\nHowever, because of the difference in backends and their limitations, they are not guaranteed to be compatible with each other. For instance, you can't set request headers in WebDriver but you can do so in Playwright or Puppeteer.")]),t._v(" "),s("p",[s("strong",[t._v("Pick one helper, as it defines how tests are executed.")]),t._v(" If requirements change it's easy to migrate to another.")]),t._v(" "),s("hr"),t._v(" "),s("p",[t._v("Refer to following guides to more information on:")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"/playwright"}},[t._v("▶ Playwright")])]),t._v(" "),s("li",[s("a",{attrs:{href:"/webdriver"}},[t._v("▶ WebDriver")])]),t._v(" "),s("li",[s("a",{attrs:{href:"/puppeteer"}},[t._v("▶ Puppeteer")])]),t._v(" "),s("li",[s("a",{attrs:{href:"/testcafe"}},[t._v("▶ TestCafe")])])]),t._v(" "),s("blockquote",[s("p",[t._v("ℹ Depending on a helper selected a list of available actions may change.")])]),t._v(" "),s("p",[t._v("To list all available commands for the current configuration run "),s("code",[t._v("codeceptjs list")]),t._v("\nor enable "),s("a",{attrs:{href:"#intellisense"}},[t._v("auto-completion by generating TypeScript definitions")]),t._v(".")]),t._v(" "),s("blockquote",[s("p",[t._v("🤔 It is possible to access API of a backend you use inside a test or a "),s("RouterLink",{attrs:{to:"/helpers/"}},[t._v("custom helper")]),t._v(". For instance, to use Puppeteer API inside a test use "),s("RouterLink",{attrs:{to:"/helpers/Puppeteer/#usepuppeteerto"}},[s("code",[t._v("I.usePuppeteerTo")])]),t._v(" inside a test. Similar methods exist for each helper.")],1)]),t._v(" "),s("h2",{attrs:{id:"writing-tests"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#writing-tests"}},[t._v("#")]),t._v(" Writing Tests")]),t._v(" "),s("p",[t._v("Tests are written from a user's perspective. There is an actor (represented as "),s("code",[t._v("I")]),t._v(") which contains actions taken from helpers. A test is written as a sequence of actions performed by an actor:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Please Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'h1'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n")])])]),s("h3",{attrs:{id:"opening-a-page"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#opening-a-page"}},[t._v("#")]),t._v(" Opening a Page")]),t._v(" "),s("p",[t._v("A test should usually start by navigating the browser to a website.")]),t._v(" "),s("p",[t._v("Start a test by opening a page. Use the "),s("code",[t._v("I.amOnPage()")]),t._v(" command for this:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// When "http://site.com" is url in config')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// -> opens http://site.com/")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/about'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// -> opens http://site.com/about")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://google.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// -> https://google.com")]),t._v("\n")])])]),s("p",[t._v("When an URL doesn't start with a protocol (http:// or https://) it is considered to be a relative URL and will be appended to the URL which was initially set-up in the config.")]),t._v(" "),s("blockquote",[s("p",[t._v("It is recommended to use a relative URL and keep the base URL in the config file, so you can easily switch between development, stage, and production environments.")])]),t._v(" "),s("h3",{attrs:{id:"locating-element"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#locating-element"}},[t._v("#")]),t._v(" Locating Element")]),t._v(" "),s("p",[t._v("Element can be found by CSS or XPath locators.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// element with CSS class user")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'//button[contains(., \"press me\")]'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// button")]),t._v("\n")])])]),s("p",[t._v("By default CodeceptJS tries to guess the locator type.\nIn order to specify the exact locator type you can pass an object called "),s("strong",[t._v("strict locator")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("css")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'div.user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("xpath")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'//div[@class=user]'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Strict locators allow to specify additional locator types:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate form element by name")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate element by React component and props")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("react")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user-profile'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("props")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("In "),s("a",{attrs:{href:"https://codecept.io/mobile/#locating-elements",target:"_blank",rel:"noopener noreferrer"}},[t._v("mobile testing"),s("OutboundLink")],1),t._v(" you can use "),s("code",[t._v("~")]),t._v(" to specify the accessibility id to locate an element. In web application you can locate elements by their "),s("code",[t._v("aria-label")]),t._v(" value.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate element by [aria-label] attribute in web")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// or by accessibility id in mobile")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~username'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[s("a",{attrs:{href:"/locators"}},[t._v("▶ Learn more about using locators in CodeceptJS")]),t._v(".")])]),t._v(" "),s("h3",{attrs:{id:"clicking"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#clicking"}},[t._v("#")]),t._v(" Clicking")]),t._v(" "),s("p",[t._v("CodeceptJS provides a flexible syntax to specify an element to click.")]),t._v(" "),s("p",[t._v("By default CodeceptJS tries to find the button or link with the exact text on it")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// search for link or button")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("If none was found, CodeceptJS tries to find a link or button containing that text. In case an image is clickable its "),s("code",[t._v("alt")]),t._v(" attribute will be checked for text inclusion. Form buttons will also be searched by name.")]),t._v(" "),s("p",[t._v("To narrow down the results you can specify a context in the second parameter.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.nav'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// search only in .nav")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("css")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'footer'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// search only in footer")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("To skip guessing the locator type, pass in a strict locator - A locator starting with '#' or '.' is considered to be CSS. Locators starting with '//' or './/' are considered to be XPath.")])]),t._v(" "),s("p",[t._v("You are not limited to buttons and links. Any element can be found by passing in valid CSS or XPath:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// click element by CSS")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#signup'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// click element located by special test-id attribute")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'//dev[@test-id=\"myid\"]'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("ℹ If click doesn't work in a test but works for user, it is possible that frontend application is not designed for automated testing. To overcome limitation of standard click in this edgecase use "),s("code",[t._v("forceClick")]),t._v(' method. It will emulate click instead of sending native event. This command will click an element no matter if this element is visible or animating. It will send JavaScript "click" event to it.')])]),t._v(" "),s("h3",{attrs:{id:"filling-fields"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#filling-fields"}},[t._v("#")]),t._v(" Filling Fields")]),t._v(" "),s("p",[t._v("Clicking the links is not what takes the most time during testing a web site. If your site consists only of links you can skip test automation. The most waste of time goes into the testing of forms. CodeceptJS provides several ways of doing that.")]),t._v(" "),s("p",[t._v("Let's submit this sample form for a test:")]),t._v(" "),s("p",[s("img",{attrs:{src:"https://user-images.githubusercontent.com/220264/80355863-494a8280-8881-11ea-9b41-ba1f07abf094.png",alt:""}})]),t._v(" "),s("div",{staticClass:"language-html extra-class"},[s("pre",{pre:!0,attrs:{class:"language-html"}},[s("code",[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("form")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("method")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("post"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("action")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("/update"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("update_form"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("label")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("user_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("Name"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("text"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("user[name]"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("user_name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("br")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("label")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("user_email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("Email"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("text"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("user[email]"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("user_email"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("br")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("label")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("user_role"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("Role"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("select")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("user_role"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("user[role]"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("option")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("value")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("0"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("Admin"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("option")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("value")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("1"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("User"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("br")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("checkbox"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("accept"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("label")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("for")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("accept"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("Accept changes"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("div")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("submit"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("submitButton"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("class")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("btn btn-primary"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("value")]),s("span",{pre:!0,attrs:{class:"token attr-value"}},[s("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("Save"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("/>")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token tag"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])]),s("p",[t._v('We need to fill in all those fields and click the "Update" button. CodeceptJS matches form elements by their label, name, or by CSS or XPath locators.')]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// we are using label to match user_name field")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Name'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Miles'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// we can use input name")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user[email]'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'miles@davis.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// select element by label, choose option by text")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("selectOption")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Role'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Admin'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// click 'Save' button, found by text")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("checkOption")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Accept'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Save'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("ℹ "),s("code",[t._v("selectOption")]),t._v(" works only with standard "),s("code",[t._v("')]),t._v(" "),s("input",{attrs:{type:"checkbox"}}),t._v(" HTML elements. If your checkbox is created by React, Vue, or as a component of any other framework, this method potentially won't work with it. Use "),s("code",[t._v("click")]),t._v(" to manipulate it.")])]),t._v(" "),s("p",[t._v("Alternative scenario:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// we are using CSS")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#user_name'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Miles'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#user_email'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'miles@davis.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// select element by label, option by value")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("selectOption")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#user_role'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// click 'Update' button, found by name")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'submitButton'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#update_form'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("To fill in sensitive data use the "),s("code",[t._v("secret")]),t._v(" function, it won't expose actual value in logs.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("secret")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'123456'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("ℹ️ Learn more about "),s("RouterLink",{attrs:{to:"/secrets/"}},[t._v("masking secret")]),t._v(" output")],1)]),t._v(" "),s("h3",{attrs:{id:"assertions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#assertions"}},[t._v("#")]),t._v(" Assertions")]),t._v(" "),s("p",[t._v("In order to verify the expected behavior of a web application, its content should be checked.\nCodeceptJS provides built-in assertions for that. They start with a "),s("code",[t._v("see")]),t._v(" (or "),s("code",[t._v("dontSee")]),t._v(") prefix.")]),t._v(" "),s("p",[t._v("The most general and common assertion is "),s("code",[t._v("see")]),t._v(", which checks visilibility of a text on a page:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Just a visible text on a page")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// text inside .msg element")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.msg'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// opposite")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSee")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Bye'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("You should provide a text as first argument and, optionally, a locator to search for a text in a context.")]),t._v(" "),s("p",[t._v("You can check that specific element exists (or not) on a page, as it was described in "),s("a",{attrs:{href:"#locating-element"}},[t._v("Locating Element")]),t._v(" section.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.notice'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.error'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Additional assertions:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeInCurrentUrl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/user/miles'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeInField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user[name]'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Miles'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeInTitle")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'My Website'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("To see all possible assertions, check the helper's reference.")]),t._v(" "),s("blockquote",[s("p",[t._v("ℹ If you need custom assertions, you can install an assertion libarary like "),s("code",[t._v("chai")]),t._v(", use grabbers to obtain information from a browser and perform assertions. However, it is recommended to put custom assertions into a helper for further reuse.")])]),t._v(" "),s("h3",{attrs:{id:"grabbing"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#grabbing"}},[t._v("#")]),t._v(" Grabbing")]),t._v(" "),s("p",[t._v("Sometimes you need to retrieve data from a page to use it in the following steps of a scenario.\nImagine the application generates a password, and you want to ensure that user can login using this password.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'login with generated password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'email'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'miles@davis.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Generate Password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" password "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabTextFrom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'email'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'miles@davis.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" password"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Log in!'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello, Miles'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("The "),s("code",[t._v("grabTextFrom")]),t._v(" action is used to retrieve the text from an element. All actions starting with the "),s("code",[t._v("grab")]),t._v(" prefix are expected to return data. In order to synchronize this step with a scenario you should pause the test execution with the "),s("code",[t._v("await")]),t._v(" keyword of ES6. To make it work, your test should be written inside a async function (notice "),s("code",[t._v("async")]),t._v(" in its definition).")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'use page title'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" password "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabTextFrom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" password"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"waiting"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#waiting"}},[t._v("#")]),t._v(" Waiting")]),t._v(" "),s("p",[t._v("In modern web applications, rendering is done on the client-side.\nSometimes that may cause delays. A test may fail while trying to click an element which has not appeared on a page yet.\nTo handle these cases, the "),s("code",[t._v("wait*")]),t._v(" methods has been introduced.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#agree_button'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// secs")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// clicks a button only when it is visible")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#agree_button'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"how-it-works"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#how-it-works"}},[t._v("#")]),t._v(" How It Works")]),t._v(" "),s("p",[t._v("Tests are written in a synchronous way. This improves the readability and maintainability of tests.\nWhile writing tests you should not think about promises, and instead should focus on the test scenario.")]),t._v(" "),s("p",[t._v("However, behind the scenes "),s("strong",[t._v("all actions are wrapped in promises")]),t._v(", inside of the "),s("code",[t._v("I")]),t._v(" object.\n"),s("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/blob/master/lib/recorder.js",target:"_blank",rel:"noopener noreferrer"}},[t._v("Global promise"),s("OutboundLink")],1),t._v(" chain is initialized before each test and all "),s("code",[t._v("I.*")]),t._v(" calls will be appended to it, as well as setup and teardown.")]),t._v(" "),s("blockquote",[s("p",[t._v("📺 "),s("a",{attrs:{href:"https://www.youtube.com/watch?v=MDLLpHAwy_s",target:"_blank",rel:"noopener noreferrer"}},[t._v("Learn how CodeceptJS"),s("OutboundLink")],1),t._v(" works with promises by watching video on YouTube")])]),t._v(" "),s("p",[t._v("If you want to get information from a running test you can use "),s("code",[t._v("await")]),t._v(" inside the "),s("strong",[t._v("async function")]),t._v(", and utilize special methods of helpers started with the "),s("code",[t._v("grab")]),t._v(" prefix.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'try grabbers'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" title "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabTitle")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("then you can use those variables in assertions:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" title "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabTitle")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" assert "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'assert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nassert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("title"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'CodeceptJS'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("It is important to understand the usage of "),s("strong",[t._v("async")]),t._v(" functions in CodeceptJS. While non-returning actions can be called without await, if an async function uses "),s("code",[t._v("grab*")]),t._v(" action it must be called with "),s("code",[t._v("await")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// a helper function")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getAllUsers")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" users "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabTextFrom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.users'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" users"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("filter")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("u")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" u"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("includes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'active'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// a test")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'try helper functions'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// we call function with await because it includes `grab`")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" users "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getAllUsers")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("If you miss "),s("code",[t._v("await")]),t._v(" you get commands unsynchrhonized. And this will result to an error like this:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("(node:446390) UnhandledPromiseRejectionWarning: ...\n at processTicksAndRejections (internal/process/task_queues.js:95:5)\n(node:446390) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)\n")])])]),s("p",[t._v("If you face that error please make sure that all async functions are called with "),s("code",[t._v("await")]),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"running-tests"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#running-tests"}},[t._v("#")]),t._v(" Running Tests")]),t._v(" "),s("p",[t._v("To launch tests use the "),s("code",[t._v("run")]),t._v(" command, and to execute tests in "),s("a",{attrs:{href:"/advanced/parallel"}},[t._v("multiple threads")]),t._v(" using "),s("code",[t._v("run-workers")]),t._v(" command.")]),t._v(" "),s("h3",{attrs:{id:"level-of-detail"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#level-of-detail"}},[t._v("#")]),t._v(" Level of Detail")]),t._v(" "),s("p",[t._v("To see the step-by-step output of running tests, add the "),s("code",[t._v("--steps")]),t._v(" flag:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run --steps\n")])])]),s("p",[t._v("To see a more detailed output add the "),s("code",[t._v("--debug")]),t._v(" flag:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run --debug\n")])])]),s("p",[t._v("To see very detailed output informations use the "),s("code",[t._v("--verbose")]),t._v(" flag:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run --verbose\n")])])]),s("h3",{attrs:{id:"filter"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#filter"}},[t._v("#")]),t._v(" Filter")]),t._v(" "),s("p",[t._v("A single test file can be executed if you provide a relative path to such a file:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run github_test.js\n\n# or\n\nnpx codeceptjs run admin/login_test.js\n")])])]),s("p",[t._v("To filter a test by name use the "),s("code",[t._v("--grep")]),t._v(" parameter, which will execute all tests with names matching the regex pattern.")]),t._v(" "),s("p",[t._v("To run all tests with the "),s("code",[t._v("slow")]),t._v(" word in it:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v('npx codeceptjs run --grep "slow"\n')])])]),s("p",[t._v("It is recommended to "),s("RouterLink",{attrs:{to:"/advanced/#tags"}},[t._v("filter tests by tags")]),t._v(".")],1),t._v(" "),s("blockquote",[s("p",[t._v("For more options see "),s("RouterLink",{attrs:{to:"/commands/#run"}},[t._v("full reference of "),s("code",[t._v("run")]),t._v(" command")]),t._v(".")],1)]),t._v(" "),s("h3",{attrs:{id:"parallel-run"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#parallel-run"}},[t._v("#")]),t._v(" Parallel Run")]),t._v(" "),s("p",[t._v("Tests can be executed in parallel mode by using "),s("a",{attrs:{href:"https://nodejs.org/api/worker_threads.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("NodeJS workers"),s("OutboundLink")],1),t._v(". Use "),s("code",[t._v("run-workers")]),t._v(" command with the number of workers (threads) to split tests into different workers.")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run-workers 3\n")])])]),s("p",[t._v("Tests are split by scenarios, not by files. Results are aggregated and shown up in the main process.")]),t._v(" "),s("h2",{attrs:{id:"configuration"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#configuration"}},[t._v("#")]),t._v(" Configuration")]),t._v(" "),s("p",[t._v("Configuration is set in the "),s("code",[t._v("codecept.conf.js")]),t._v(" file which was created during the "),s("code",[t._v("init")]),t._v(" process.\nInside the config file you can enable and configure helpers and plugins, and set bootstrap and teardown scripts.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v("exports"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// enabled helpers with their configs")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("plugins")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// list of used plugins")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("include")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// current actor and page objects")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("▶ See complete "),s("a",{attrs:{href:"/configuration"}},[t._v("configuration reference")]),t._v(".")])]),t._v(" "),s("p",[t._v("You can have multiple configuration files for a the same project, in this case you can specify a config file to be used with "),s("code",[t._v("-c")]),t._v(" when running.")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run -c codecept.ci.conf.js\n")])])]),s("p",[t._v("Tuning configuration for helpers like WebDriver, Puppeteer can be hard, as it requires good understanding of how these technologies work. Use the "),s("a",{attrs:{href:"https://github.com/codeceptjs/configure",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("@codeceptjs/configure")]),s("OutboundLink")],1),t._v(" package with common configuration recipes.")]),t._v(" "),s("p",[t._v("For instance, you can set the window size or toggle headless mode, no matter of which helpers are actually used.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" setHeadlessWhen"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setWindowSize "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@codeceptjs/configure'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// run headless when CI environment variable set")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setHeadlessWhen")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("process"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("CI")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// set window size for any helper: Puppeteer, WebDriver, TestCafe")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setWindowSize")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1600")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1200")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nexports"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("▶ See more "),s("a",{attrs:{href:"https://github.com/codeceptjs/configure",target:"_blank",rel:"noopener noreferrer"}},[t._v("configuration recipes"),s("OutboundLink")],1)])]),t._v(" "),s("h2",{attrs:{id:"debug"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#debug"}},[t._v("#")]),t._v(" Debug")]),t._v(" "),s("p",[t._v("CodeceptJS allows to write and debug tests on the fly while keeping your browser opened.\nBy using the interactive shell you can stop execution at any point and type in any CodeceptJS commands.")]),t._v(" "),s("p",[t._v("This is especially useful while writing a new scratch. After opening a page call "),s("code",[t._v("pause()")]),t._v(" to start interacting with a page:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pause")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Try to perform your scenario step by step. Then copy succesful commands and insert them into a test.")]),t._v(" "),s("h3",{attrs:{id:"pause"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#pause"}},[t._v("#")]),t._v(" Pause")]),t._v(" "),s("p",[t._v("Test execution can be paused in any place of a test with "),s("code",[t._v("pause()")]),t._v(" call.\nVariables can also be passed to "),s("code",[t._v("pause({data: 'hi', func: () => console.log('hello')})")]),t._v(" which can be accessed in Interactive shell.")]),t._v(" "),s("p",[t._v("This launches the interactive console where you can call any action from the "),s("code",[t._v("I")]),t._v(" object.")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v(" Interactive shell started\n Press ENTER to resume test\n Use JavaScript syntax to try steps in action\n - Press ENTER to run the next step\n - Press TAB twice to see all available commands\n - Type exit + Enter to exit the interactive shell\n - Prefix => to run js commands\n I.\n")])])]),s("p",[t._v("Type in different actions to try them, copy and paste successful ones into the test file.")]),t._v(" "),s("p",[t._v("Press "),s("code",[t._v("ENTER")]),t._v(" to resume test execution.")]),t._v(" "),s("p",[t._v("To "),s("strong",[t._v("debug test step-by-step")]),t._v(" press Enter, the next step will be executed and interactive shell will be shown again.")]),t._v(" "),s("p",[t._v("To see all available commands, press TAB two times to see list of all actions included in the "),s("code",[t._v("I")]),t._v(" object.")]),t._v(" "),s("blockquote",[s("p",[t._v("The interactive shell can be started outside of test context by running "),s("code",[t._v("npx codeceptjs shell")])])]),t._v(" "),s("p",[t._v("PageObjects and other variables can also be passed to as object:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pause")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" loginPage"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("data")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'hi'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("func")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'hello'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Inside a pause mode you can use "),s("code",[t._v("loginPage")]),t._v(", "),s("code",[t._v("data")]),t._v(", "),s("code",[t._v("func")]),t._v(" variables.\nArbitrary JavaScript code can be executed when used "),s("code",[t._v("=>")]),t._v(" prefix:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" loginPage"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("func")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),t._v("\n")])])]),s("h3",{attrs:{id:"pause-on-fail"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#pause-on-fail"}},[t._v("#")]),t._v(" Pause on Fail")]),t._v(" "),s("p",[t._v("To start interactive pause automatically for a failing test you can run tests with "),s("RouterLink",{attrs:{to:"/plugins/#pauseonfail"}},[t._v("pauseOnFail Plugin")]),t._v(".\nWhen a test fails, the pause mode will be activated, so you can inspect current browser session before it is closed.")],1),t._v(" "),s("blockquote",[s("p",[s("strong",[s("RouterLink",{attrs:{to:"/plugins/#pauseOnFail"}},[t._v("pauseOnFail plugin")]),t._v(" can be used")],1),t._v(" for new setups")])]),t._v(" "),s("p",[t._v("To run tests with pause on fail enabled use "),s("code",[t._v("-p pauseOnFail")]),t._v(" option")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run -p pauseOnFail\n")])])]),s("blockquote",[s("p",[t._v("To enable pause after a test without a plugin you can use "),s("code",[t._v("After(pause)")]),t._v(" inside a test file.")])]),t._v(" "),s("h3",{attrs:{id:"screenshot-on-failure"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#screenshot-on-failure"}},[t._v("#")]),t._v(" Screenshot on Failure")]),t._v(" "),s("p",[t._v("By default CodeceptJS saves a screenshot of a failed test.\nThis can be configured in "),s("RouterLink",{attrs:{to:"/plugins/#screenshotonfail"}},[t._v("screenshotOnFail Plugin")])],1),t._v(" "),s("blockquote",[s("p",[s("strong",[s("RouterLink",{attrs:{to:"/plugins/#screenshotonfail"}},[t._v("screenshotOnFail plugin")]),t._v(" is enabled by default")],1),t._v(" for new setups")])]),t._v(" "),s("h3",{attrs:{id:"step-by-step-report"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-by-step-report"}},[t._v("#")]),t._v(" Step By Step Report")]),t._v(" "),s("p",[t._v("To see how the test was executed, use "),s("RouterLink",{attrs:{to:"/plugins/#stepbystepreport"}},[t._v("stepByStepReport Plugin")]),t._v(". It saves a screenshot of each passed step and shows them in a nice slideshow.")],1),t._v(" "),s("h2",{attrs:{id:"before"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#before"}},[t._v("#")]),t._v(" Before")]),t._v(" "),s("p",[t._v("Common preparation steps like opening a web page or logging in a user, can be placed in the "),s("code",[t._v("Before")]),t._v(" or "),s("code",[t._v("Background")]),t._v(" hooks:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'CodeceptJS Demonstration'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Before")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// or Background")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/documentation'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'test some forms'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Create User'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'User is valid'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeInCurrentUrl")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/documentation'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'test title'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeInTitle")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Example application'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Same as "),s("code",[t._v("Before")]),t._v(" you can use "),s("code",[t._v("After")]),t._v(" to run teardown for each scenario.")]),t._v(" "),s("h2",{attrs:{id:"beforesuite"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#beforesuite"}},[t._v("#")]),t._v(" BeforeSuite")]),t._v(" "),s("p",[t._v("If you need to run complex a setup before all tests and have to teardown this afterwards, you can use the "),s("code",[t._v("BeforeSuite")]),t._v(" and "),s("code",[t._v("AfterSuite")]),t._v(" functions.\n"),s("code",[t._v("BeforeSuite")]),t._v(" and "),s("code",[t._v("AfterSuite")]),t._v(" have access to the "),s("code",[t._v("I")]),t._v(" object, but "),s("code",[t._v("BeforeSuite/AfterSuite")]),t._v(" don't have any access to the browser, because it's not running at this moment.\nYou can use them to execute handlers that will setup your environment. "),s("code",[t._v("BeforeSuite/AfterSuite")]),t._v(" will work only for the file it was declared in (so you can declare different setups for files)")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("BeforeSuite")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("syncDown")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'testfolder'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("AfterSuite")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("syncUp")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'testfolder'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clearDir")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'testfolder'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"retries"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#retries"}},[t._v("#")]),t._v(" Retries")]),t._v(" "),s("h3",{attrs:{id:"auto-retry"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#auto-retry"}},[t._v("#")]),t._v(" Auto Retry")]),t._v(" "),s("p",[t._v("Each failed step is auto-retried by default via "),s("RouterLink",{attrs:{to:"/plugins/#retryfailedstep"}},[t._v("retryFailedStep Plugin")]),t._v(".\nIf this is not expected, this plugin can be disabled in a config.")],1),t._v(" "),s("blockquote",[s("p",[s("strong",[s("RouterLink",{attrs:{to:"/plugins/#retryfailedstep"}},[t._v("retryFailedStep plugin")]),t._v(" is enabled by default")],1),t._v(" incide global configuration")])]),t._v(" "),s("h3",{attrs:{id:"retry-step"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#retry-step"}},[t._v("#")]),t._v(" Retry Step")]),t._v(" "),s("p",[t._v("Unless you use retryFailedStep plugin you can manually control retries in your project.")]),t._v(" "),s("p",[t._v("If you have a step which often fails, you can retry execution for this single step.\nUse the "),s("code",[t._v("retry()")]),t._v(" function before an action to ask CodeceptJS to retry it on failure:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("retry")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Welcome'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("If you'd like to retry a step more than once, pass the amount as a parameter:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("retry")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Welcome'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Additional options can be provided to "),s("code",[t._v("retry")]),t._v(", so you can set the additional options (defined in "),s("a",{attrs:{href:"https://www.npmjs.com/package/promise-retry",target:"_blank",rel:"noopener noreferrer"}},[t._v("promise-retry"),s("OutboundLink")],1),t._v(" library).")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// retry action 3 times waiting for 0.1 second before next try")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("retry")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("retries")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("minTimeout")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// retry action 3 times waiting no more than 3 seconds for last retry")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("retry")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("retries")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("maxTimeout")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3000")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// retry 2 times if error with message 'Node not visible' happens")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("retry")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("retries")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("when")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("err")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" err"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("message "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Node not visible'")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Pass a function to the "),s("code",[t._v("when")]),t._v(" option to retry only when an error matches the expected one.")]),t._v(" "),s("h3",{attrs:{id:"retry-multiple-steps"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#retry-multiple-steps"}},[t._v("#")]),t._v(" Retry Multiple Steps")]),t._v(" "),s("p",[t._v("To retry a group of steps enable "),s("RouterLink",{attrs:{to:"/plugins/#retryto"}},[t._v("retryTo plugin")]),t._v(":")],1),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// retry these steps 5 times before failing")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("retryTo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("tryNum")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("switchTo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#editor frame'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Open'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Opened'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"retry-scenario"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#retry-scenario"}},[t._v("#")]),t._v(" Retry Scenario")]),t._v(" "),s("p",[t._v("When you need to rerun scenarios a few times, add the "),s("code",[t._v("retries")]),t._v(" option to the "),s("code",[t._v("Scenario")]),t._v(" declaration.")]),t._v(" "),s("p",[t._v("CodeceptJS implements retries the same way "),s("a",{attrs:{href:"https://mochajs.org#retry-tests",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mocha does"),s("OutboundLink")],1),t._v(";\nYou can set the number of a retries for a feature:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Really complex'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// test goes here")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("retry")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// alternative")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Really complex'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("retries")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("This scenario will be restarted two times on a failure.\nUnlike retry step, there is no "),s("code",[t._v("when")]),t._v(" condition supported for retries on a scenario level.")]),t._v(" "),s("h3",{attrs:{id:"retry-before"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#retry-before"}},[t._v("#")]),t._v(" Retry Before "),s("Badge",{attrs:{text:"Since 3.4",type:"warning"}})],1),t._v(" "),s("p",[t._v("To retry "),s("code",[t._v("Before")]),t._v(", "),s("code",[t._v("BeforeSuite")]),t._v(", "),s("code",[t._v("After")]),t._v(", "),s("code",[t._v("AfterSuite")]),t._v(" hooks, add corresponding option to a "),s("code",[t._v("Feature")]),t._v(":")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("retryBefore")])]),t._v(" "),s("li",[s("code",[t._v("retryBeforeSuite")])]),t._v(" "),s("li",[s("code",[t._v("retryAfter")])]),t._v(" "),s("li",[s("code",[t._v("retryAfterSuite")])])]),t._v(" "),s("p",[t._v("For instance, to retry Before hook 3 times:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'this have a flaky Befure'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("retryBefore")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("Multiple options of different values can be set at the same time")]),t._v(" "),s("h3",{attrs:{id:"retry-feature"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#retry-feature"}},[t._v("#")]),t._v(" Retry Feature")]),t._v(" "),s("p",[t._v("To set this option for all scenarios in a file, add "),s("code",[t._v("retry")]),t._v(" to a feature:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Complex JS Stuff'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("retry")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// or")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Complex JS Stuff'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("retries")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("Every Scenario inside this feature will be rerun 3 times.\nYou can make an exception for a specific scenario by passing the "),s("code",[t._v("retries")]),t._v(" option to a Scenario.")]),t._v(" "),s("h3",{attrs:{id:"retry-configuration"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#retry-configuration"}},[t._v("#")]),t._v(" Retry Configuration "),s("Badge",{attrs:{text:"Since 3.4",type:"warning"}})],1),t._v(" "),s("p",[t._v("It is possible to set retry rules globally via "),s("code",[t._v("retry")]),t._v(" config option. The configuration is flexible and allows multiple formats.\nThe simplest config would be:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside codecept.conf.js")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("retry")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v("\n")])])]),s("p",[t._v("This will enable Feature Retry for all executed feature, retrying failing tests 3 times.")]),t._v(" "),s("p",[t._v("An object can be used to tune retries of a Before/After hook, Scenario or Feature")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside codecept.conf.js")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("retry")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Before")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("BeforeSuite")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("After")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("AfterSuite")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Multiple retry configs can be added via array. To use different retry configs for different subset of tests use "),s("code",[t._v("grep")]),t._v(" option inside a retry config:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside codecept.conf.js")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("retry")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// enable this config only for flaky tests")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("grep")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@flaky'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Before")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// retry less when running slow tests")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("grep")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@slow'")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Before")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// retry all BeforeSuite ")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("BeforeSuite")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),s("p",[t._v("When using "),s("code",[t._v("grep")]),t._v(" with "),s("code",[t._v("Before")]),t._v(", "),s("code",[t._v("After")]),t._v(", "),s("code",[t._v("BeforeSuite")]),t._v(", "),s("code",[t._v("AfterSuite")]),t._v(", a suite title will be checked for included value.")]),t._v(" "),s("blockquote",[s("p",[t._v("ℹ️ "),s("code",[t._v("grep")]),t._v(" value can be string or regexp")])]),t._v(" "),s("p",[t._v("Rules are applied in the order of array element, so the last option will override a previous one. Global retries config can be overridden in a file as described previously.")]),t._v(" "),s("h3",{attrs:{id:"retry-run"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#retry-run"}},[t._v("#")]),t._v(" Retry Run")]),t._v(" "),s("p",[t._v('On the highest level of the "retry pyramid" there is an option to retry a complete run multiple times.\nEven this is the slowest option of all, it can be helpful to detect flaky tests.')]),t._v(" "),s("p",[s("a",{attrs:{href:"https://codecept.io/commands/#run-rerun",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("run-rerun")]),s("OutboundLink")],1),t._v(" command will restart the run multiple times to values you provide. You can set minimal and maximal number of restarts in configuration file.")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run-rerun\n")])])]),s("p",[s("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/pull/231#issuecomment-249554933",target:"_blank",rel:"noopener noreferrer"}},[t._v("Here are some ideas"),s("OutboundLink")],1),t._v(" on where to use BeforeSuite hooks.")]),t._v(" "),s("h2",{attrs:{id:"within"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#within"}},[t._v("#")]),t._v(" Within")]),t._v(" "),s("p",[t._v("To specify the exact area on a page where actions can be performed you can use the "),s("code",[t._v("within")]),t._v(" function.\nEverything executed in its context will be narrowed to context specified by locator:")]),t._v(" "),s("p",[t._v("Usage: "),s("code",[t._v("within('section', ()=>{})")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://github.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("within")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.js-signup-form'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user[login]'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'User'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user[email]'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user@user.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user[password]'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user@user.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'button'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'There were problems creating your account.'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("⚠ "),s("code",[t._v("within")]),t._v(" can cause problems when used incorrectly. If you see a weird behavior of a test try to refactor it to not use "),s("code",[t._v("within")]),t._v(". It is recommended to keep within for simplest cases when possible.\nSince "),s("code",[t._v("within")]),t._v(" returns a Promise, it may be necessary to "),s("code",[t._v("await")]),t._v(" the result even when you're not intending to use the return value.")])]),t._v(" "),s("p",[s("code",[t._v("within")]),t._v(" can also work with IFrames. A special "),s("code",[t._v("frame")]),t._v(" locator is required to locate the iframe and get into its context.")]),t._v(" "),s("p",[t._v("See example:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("within")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("frame")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"#editor"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Page'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("ℹ IFrames can also be accessed via "),s("code",[t._v("I.switchTo")]),t._v(" command of a corresponding helper.")])]),t._v(" "),s("p",[t._v("Nested IFrames can be set by passing an array "),s("em",[t._v("(WebDriver & Puppeteer only)")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("within")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("frame")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('".content"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"#editor"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Page'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("When running steps inside, a within block will be shown with a shift:")]),t._v(" "),s("p",[s("img",{attrs:{src:"/img/within.png",alt:"within"}})]),t._v(" "),s("p",[t._v("Within can return a value, which can be used in a scenario:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside async function")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" val "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("within")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#sidebar'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabTextFrom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("css")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'h1'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Description'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"conditional-actions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#conditional-actions"}},[t._v("#")]),t._v(" Conditional Actions")]),t._v(" "),s("p",[t._v('There is a way to execute unsuccessful actions to without failing a test.\nThis might be useful when you might need to click "Accept cookie" button but probably cookies were already accepted.\nTo handle these cases '),s("code",[t._v("tryTo")]),t._v(" function was introduced:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("tryTo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Accept'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.cookies'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("You may also use "),s("code",[t._v("tryTo")]),t._v(" for cases when you deal with uncertainty on page:")]),t._v(" "),s("ul",[s("li",[t._v("A/B testing")]),t._v(" "),s("li",[t._v("soft assertions")]),t._v(" "),s("li",[t._v("cookies & gdpr")])]),t._v(" "),s("p",[s("code",[t._v("tryTo")]),t._v(" function is enabled by default via "),s("RouterLink",{attrs:{to:"/plugins/#tryto"}},[t._v("tryTo plugin")])],1),t._v(" "),s("h2",{attrs:{id:"comments"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#comments"}},[t._v("#")]),t._v(" Comments")]),t._v(" "),s("p",[t._v("There is a simple way to add additional comments to your test scenario:\nUse the "),s("code",[t._v("say")]),t._v(" command to print information to screen:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("say")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I am going to publish post'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("say")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I enter title and body'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("say")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I expect post is visible on site'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Use the second parameter to pass in a color value (ASCII).")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("say")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'This is red'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'red'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//red is used")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("say")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'This is blue'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'blue'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//blue is used")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("say")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'This is by default'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//cyan is used")]),t._v("\n")])])]),s("h2",{attrs:{id:"intellisense"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#intellisense"}},[t._v("#")]),t._v(" IntelliSense")]),t._v(" "),s("p",[s("img",{attrs:{src:"/img/edit.gif",alt:"Edit"}})]),t._v(" "),s("p",[t._v("To get autocompletion when working with CodeceptJS, use Visual Studio Code or another IDE that supports TypeScript Definitions.")]),t._v(" "),s("p",[t._v("Generate step definitions with:")]),t._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[t._v("npx codeceptjs def\n")])])]),s("p",[t._v("Create a file called "),s("code",[t._v("jsconfig.json")]),t._v(" in your project root directory, unless you already have one.")]),t._v(" "),s("div",{staticClass:"language-jsconfig.json extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v('{\n "compilerOptions": {\n "allowJs": true,\n }\n}\n')])])]),s("p",[t._v("Alternatively, you can include "),s("code",[t._v('/// ')]),t._v(" into your test files\nto get method autocompletion while writing tests.")]),t._v(" "),s("h2",{attrs:{id:"multiple-sessions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#multiple-sessions"}},[t._v("#")]),t._v(" Multiple Sessions")]),t._v(" "),s("p",[t._v("CodeceptJS allows to run several browser sessions inside a test. This can be useful for testing communication between users inside a chat or other systems. To open another browser use the "),s("code",[t._v("session()")]),t._v(" function as shown in the example:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'test app'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/chat'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'name'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Sign In'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello, davert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("session")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// another session started")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/chat'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'name'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Sign In'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello, john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// switching back to default session")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'message'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hi, john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// there is a message from current user")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'me: Hi, john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.messages'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("session")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// let's check if john received it")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert: Hi, john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.messages'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("The "),s("code",[t._v("session")]),t._v(" function expects the first parameter to be the name of the session. You can switch back to this session by using the same name.")]),t._v(" "),s("p",[t._v("You can override the configuration for the session by passing a second parameter:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("session")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'firefox'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// run this steps in firefox")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("or just start the session without switching to it. Call "),s("code",[t._v("session")]),t._v(" passing only its name:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'test'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// opens 3 additional browsers")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("session")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("session")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'mary'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("session")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'jane'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// switch to session by its name")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("session")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'mary'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[s("code",[t._v("session")]),t._v(" can return a value which can be used in a scenario:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside async function")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" val "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("session")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/info'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabTextFrom")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("css")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'h1'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Description'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" val"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Functions passed into a session can use the "),s("code",[t._v("I")]),t._v(" object, page objects, and any other objects declared for the scenario.\nThis function can also be declared as async (but doesn't work as generator).")]),t._v(" "),s("p",[t._v("Also, you can use "),s("code",[t._v("within")]),t._v(" inside a session, but you can't call session from inside "),s("code",[t._v("within")]),t._v(".")]),t._v(" "),s("h2",{attrs:{id:"skipping"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#skipping"}},[t._v("#")]),t._v(" Skipping")]),t._v(" "),s("p",[t._v("Like in Mocha you can use "),s("code",[t._v("x")]),t._v(" and "),s("code",[t._v("only")]),t._v(" to skip tests or to run a single test.")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("xScenario")]),t._v(" - skips current test")]),t._v(" "),s("li",[s("code",[t._v("Scenario.skip")]),t._v(" - skips current test")]),t._v(" "),s("li",[s("code",[t._v("Scenario.only")]),t._v(" - executes only the current test")]),t._v(" "),s("li",[s("code",[t._v("xFeature")]),t._v(" - skips current suite "),s("Badge",{attrs:{text:"Since 2.6.6",type:"warning"}})],1),t._v(" "),s("li",[s("code",[t._v("Feature.skip")]),t._v(" - skips the current suite "),s("Badge",{attrs:{text:"Since 2.6.6",type:"warning"}})],1)]),t._v(" "),s("h2",{attrs:{id:"todo-test"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#todo-test"}},[t._v("#")]),t._v(" Todo Test")]),t._v(" "),s("p",[t._v("You can use "),s("code",[t._v("Scenario.todo")]),t._v(" when you are planning on writing tests.")]),t._v(" "),s("p",[t._v("This test will be skipped like with regular "),s("code",[t._v("Scenario.skip")]),t._v(' but with additional message "Test not implemented!":')]),t._v(" "),s("p",[t._v("Use it with a test body as a test plan:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v("Scenario"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("todo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Test'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/**\n * 1. Click to field\n * 2. Fill field\n *\n * Result:\n * 3. Field contains text\n */")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Or even without a test body:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v("Scenario"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("todo")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Test'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/36.3a3038c0.js b/assets/js/36.3a3038c0.js new file mode 100644 index 00000000..3196bef6 --- /dev/null +++ b/assets/js/36.3a3038c0.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[36],{336:function(t,s,a){"use strict";a.r(s);var e=a(14),n=Object(e.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"behavior-driven-development"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#behavior-driven-development"}},[t._v("#")]),t._v(" Behavior Driven Development")]),t._v(" "),s("p",[t._v("Behavior Driven Development (BDD) is a popular software development methodology. BDD is considered an extension of TDD, and is greatly inspired by "),s("a",{attrs:{href:"https://agilemanifesto.org/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Agile"),s("OutboundLink")],1),t._v(" practices. The primary reason to choose BDD as your development process is to break down communication barriers between business and technical teams. BDD encourages the use of automated testing to verify all documented features of a project from the very beginning. This is why it is common to talk about BDD in the context of test frameworks (like CodeceptJS). The BDD approach, however, is about much more than testing - it is a common language for all team members to use during the development process.")]),t._v(" "),s("h2",{attrs:{id:"what-is-behavior-driven-development"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#what-is-behavior-driven-development"}},[t._v("#")]),t._v(" What is Behavior Driven Development")]),t._v(" "),s("p",[t._v("BDD was introduced by "),s("a",{attrs:{href:"https://dannorth.net/introducing-bdd/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Dan North"),s("OutboundLink")],1),t._v(". He described it as:")]),t._v(" "),s("blockquote",[s("p",[t._v("outside-in, pull-based, multiple-stakeholder, multiple-scale, high-automation, agile methodology. It describes a cycle of interactions with well-defined outputs, resulting in the delivery of working, tested software that matters.")])]),t._v(" "),s("p",[t._v('BDD has its own evolution from the days it was born, started by replacing "test" to "should" in unit tests, and moving towards powerful tools like Cucumber and Behat, which made user stories (human-readable text) to be executed as an acceptance test.')]),t._v(" "),s("p",[t._v("The idea of story BDD can be narrowed to:")]),t._v(" "),s("ul",[s("li",[t._v("describe features in a scenario with a formal text")]),t._v(" "),s("li",[t._v("use examples to make abstract things concrete")]),t._v(" "),s("li",[t._v("implement each step of a scenario for testing")]),t._v(" "),s("li",[t._v("write actual code implementing the feature")])]),t._v(" "),s("p",[t._v("By writing every feature in User Story format that is automatically executable as a test we ensure that: business, developers, QAs and managers are in the same boat.")]),t._v(" "),s("p",[t._v("BDD encourages exploration and debate in order to formalize the requirements and the features that needs to be implemented by requesting to write the User Stories in a way that everyone can understand.")]),t._v(" "),s("p",[t._v("By making tests to be a part of User Story, BDD allows non-technical personnel to write (or edit) Acceptance tests.")]),t._v(" "),s("p",[t._v("With this procedure we also ensure that everyone in a team knows what has been developed, what has not, what has been tested and what has not.")]),t._v(" "),s("h3",{attrs:{id:"ubiquitous-language"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#ubiquitous-language"}},[t._v("#")]),t._v(" Ubiquitous Language")]),t._v(" "),s("p",[t._v("The ubiquitous language is always referred as "),s("em",[t._v("common")]),t._v(" language. That it is the main benefit. It is not a couple of our business specification's words, and not a couple of developer's technical terms. It is a common words and terms that can be understood by people for whom we are building the software and should be understood by developers. Establishing correct communication between this two groups people is vital for building successful project that will fit the domain and fulfill all business needs.")]),t._v(" "),s("p",[t._v("Each feature of a product should be born from a talk between")]),t._v(" "),s("ul",[s("li",[t._v("business (analysts, product owner)")]),t._v(" "),s("li",[t._v("developers")]),t._v(" "),s("li",[t._v("QAs")])]),t._v(" "),s("p",[t._v('which are known in BDD as "three amigos".')]),t._v(" "),s("p",[t._v("Such talks should produce written stories. There should be an actor that doing some things, the feature that should be fulfilled within the story and the result achieved.")]),t._v(" "),s("p",[t._v("We can try to write such simple story:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("As a customer I want to buy several products\nI put first product with $600 price to my cart\nAnd then another one with $1000 price\nWhen I go to checkout process\nI should see that total number of products I want to buy is 2\nAnd my order amount is $1600\n")])])]),s("p",[t._v("As we can see this simple story highlights core concepts that are called "),s("em",[t._v("contracts")]),t._v(". We should fulfill those contracts to model software correctly. But how we can verify that those contracts are being satisfied? "),s("a",{attrs:{href:"https://cucumber.io",target:"_blank",rel:"noopener noreferrer"}},[t._v("Cucumber"),s("OutboundLink")],1),t._v(" introduced a special language for such stories called "),s("strong",[t._v("Gherkin")]),t._v(". Same story transformed to Gherkin will look like this:")]),t._v(" "),s("div",{staticClass:"language-gherkin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-gherkin"}},[s("code",[s("span",{pre:!0,attrs:{class:"token feature"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("Feature:")]),s("span",{pre:!0,attrs:{class:"token important"}},[t._v(" checkout process")]),t._v("\n In order to buy products\n As a customer\n I want to be able to buy several products\n")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token scenario"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("Scenario:")]),s("span",{pre:!0,attrs:{class:"token important"}})]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("Given")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" have product with $600 price in my cart\n "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("And")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" have product with $1000 price\n "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("When")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" go to checkout process\n "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("Then")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" should see that total number of products is 2\n "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("And")]),t._v(" my order amount is $1600\n")])])]),s("p",[s("strong",[t._v("CodeceptJS can execute this scenario step by step as an automated test")]),t._v(".\nEvery step in this scenario requires a code which defines it.")]),t._v(" "),s("h2",{attrs:{id:"gherkin"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#gherkin"}},[t._v("#")]),t._v(" Gherkin")]),t._v(" "),s("p",[t._v("Let's learn some more about Gherkin format and then we will see how to execute it with CodeceptJS. We can enable Gherkin for current project by running "),s("code",[t._v("gherkin:init")]),t._v(" command on "),s("strong",[t._v("already initialized project")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs gherkin:init\n")])])]),s("p",[t._v("It will add "),s("code",[t._v("gherkin")]),t._v(" section to the current config. It will also prepare directories for features and step definition. And it will create the first feature file for you.")]),t._v(" "),s("h3",{attrs:{id:"features"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#features"}},[t._v("#")]),t._v(" Features")]),t._v(" "),s("p",[t._v("Whenever you start writing a story you are describing a specific feature of an application, with a set of scenarios and examples describing this feature. Let's open a feature file created by "),s("code",[t._v("gherkin:init")]),t._v(" command, which is "),s("code",[t._v("feature/basic.feature")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-gherkin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-gherkin"}},[s("code",[s("span",{pre:!0,attrs:{class:"token feature"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("Feature:")]),s("span",{pre:!0,attrs:{class:"token important"}},[t._v(" Business rules")]),t._v("\n In order to achieve my goals\n As a persona\n I want to be able to interact with a system\n")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token scenario"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("Scenario:")]),s("span",{pre:!0,attrs:{class:"token important"}},[t._v(" do something")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("Given")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" have a defined step\n")])])]),s("p",[t._v("This text should be rewritten to follow your buisness rules. Don't think about a web interface for a while.\nThink about how user interacts with your system and what goals they want to achieve. Then write interaction scenarios.")]),t._v(" "),s("h4",{attrs:{id:"scenarios"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#scenarios"}},[t._v("#")]),t._v(" Scenarios")]),t._v(" "),s("p",[t._v("Scenarios are live examples of feature usage. Inside a feature file it should be written inside a "),s("em",[t._v("Feature")]),t._v(" block. Each scenario should contain its title:")]),t._v(" "),s("div",{staticClass:"language-gherkin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-gherkin"}},[s("code",[s("span",{pre:!0,attrs:{class:"token feature"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("Feature:")]),s("span",{pre:!0,attrs:{class:"token important"}},[t._v(" checkout")]),t._v("\n In order to buy product\n As a customer\n I need to be able to checkout the selected products\n")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token scenario"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("Scenario:")]),s("span",{pre:!0,attrs:{class:"token important"}},[t._v(" order several products")])]),t._v("\n")])])]),s("p",[t._v("Scenarios are written in step-by-step manner using Given-When-Then approach. At start, scenario should describe its context with "),s("strong",[t._v("Given")]),t._v(" keyword:")]),t._v(" "),s("div",{staticClass:"language-gherkin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-gherkin"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("Given")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" have product with $600 price in my cart\n "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("And")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" have product with $1000 price in my cart\n")])])]),s("p",[t._v("Here we also use word "),s("strong",[t._v("And")]),t._v(" to extend the Given and not to repeat it in each line.")]),t._v(" "),s("p",[t._v("This is how we described the initial conditions. Next, we perform some action. We use "),s("strong",[t._v("When")]),t._v(" keyword for it:")]),t._v(" "),s("div",{staticClass:"language-gherkin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-gherkin"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("When")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" go to checkout process\n")])])]),s("p",[t._v("And in the end we are verifying our expectation using "),s("strong",[t._v("Then")]),t._v(" keyword. The action changed the initial given state, and produced some results. Let's check that those results are what we actually expect.")]),t._v(" "),s("div",{staticClass:"language-gherkin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-gherkin"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("Then")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" should see that total number of products is 2\n "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("And")]),t._v(" my order amount is $1600\n")])])]),s("p",[t._v("This scenarios are nice as live documentation but they do not test anything yet. What we need next is to define how to run those steps.\nSteps can be defined by executing "),s("code",[t._v("gherkin:snippets")]),t._v(" command:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("npx codeceptjs gherkin:snippets "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("--path"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token environment constant"}},[t._v("PATH")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("--feature"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token environment constant"}},[t._v("PATH")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),s("p",[t._v("This will produce code templates for all undefined steps in the .feature files.\nBy default, it will scan all of the "),s("code",[t._v(".feature")]),t._v(" files specified in the "),s("code",[t._v("gherkin.features")]),t._v(" section of the config and produce code templates for all undefined steps. If the "),s("code",[t._v("--feature")]),t._v(" option is specified, it will scan the specified .feature file(s).\nThe stub definitions by default will be placed into the first file specified in the "),s("code",[t._v("gherkin.steps")]),t._v(" section of the config. However, you may also use "),s("code",[t._v("--path")]),t._v(" to specify a specific file in which to place all undefined steps. This file must exist and be in the `gherkin.steps array of the config.\nOur next step will be to define those steps and transforming feature-file into a valid test.")]),t._v(" "),s("h3",{attrs:{id:"step-definitions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#step-definitions"}},[t._v("#")]),t._v(" Step Definitions")]),t._v(" "),s("p",[t._v("Step definitions are placed in JavaScript file with Given/When/Then functions that map strings from feature file to functions:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// use I and productPage via inject() function")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" productPage "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("inject")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// you can provide RegEx to match corresponding steps")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Given")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token regex"}},[s("span",{pre:!0,attrs:{class:"token regex-delimiter"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token regex-source language-regex"}},[t._v("I have product with \\$(\\d+) price")]),s("span",{pre:!0,attrs:{class:"token regex-delimiter"}},[t._v("/")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("price")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/products'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n productPage"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("create")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" price "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Add to cart'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// or a simple string")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("When")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I go to checkout process'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Checkout'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// parameters are passed in via Cucumber expressions")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Then")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I should see that total number of products is {int}'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("num")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("num"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.cart'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Then")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'my order amount is ${int}'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("sum")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// eslint-disable-line")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Total: '")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" sum"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Steps can be either strings or regular expressions. Parameters from string are passed as function arguments. To define parameters in a string we use "),s("a",{attrs:{href:"https://github.com/cucumber/cucumber-expressions#readme",target:"_blank",rel:"noopener noreferrer"}},[t._v("Cucumber expressions"),s("OutboundLink")],1)]),t._v(" "),s("p",[t._v("To list all defined steps run "),s("code",[t._v("gherkin:steps")]),t._v(" command:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("npx codeceptjs gherkin:steps\n")])])]),s("p",[t._v("Use "),s("code",[t._v("grep")]),t._v(" to find steps in a list (grep works on Linux & MacOS):")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs gherkin:steps | grep user\n")])])]),s("p",[t._v("To run tests and see step-by step output use "),s("code",[t._v("--steps")]),t._v(" optoin:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run --steps\n")])])]),s("p",[t._v("To see not only business steps but an actual performed steps use "),s("code",[t._v("--debug")]),t._v(" flag:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run --debug\n")])])]),s("h2",{attrs:{id:"advanced-gherkin"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#advanced-gherkin"}},[t._v("#")]),t._v(" Advanced Gherkin")]),t._v(" "),s("p",[t._v("Let's improve our BDD suite by using the advanced features of Gherkin language.")]),t._v(" "),s("h3",{attrs:{id:"background"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#background"}},[t._v("#")]),t._v(" Background")]),t._v(" "),s("p",[t._v("If a group of scenarios have the same initial steps, let's that for dashboard we need always need to be logged in as administrator. We can use "),s("em",[t._v("Background")]),t._v(" section to do the required preparations and not to repeat same steps across scenarios.")]),t._v(" "),s("div",{staticClass:"language-gherkin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-gherkin"}},[s("code",[s("span",{pre:!0,attrs:{class:"token feature"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("Feature:")]),s("span",{pre:!0,attrs:{class:"token important"}},[t._v(" Dashboard")]),t._v("\n In order to view current state of business\n As an owner\n I need to be able to see reports on dashboard\n")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token scenario"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("Background:")]),s("span",{pre:!0,attrs:{class:"token important"}})]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("Given")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" am logged in as administrator\n "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("And")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" open dashboard page\n")])])]),s("p",[t._v("Steps in background are defined the same way as in scenarios.")]),t._v(" "),s("h3",{attrs:{id:"tables"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#tables"}},[t._v("#")]),t._v(" Tables")]),t._v(" "),s("p",[t._v('Scenarios can become more descriptive when you represent repeating data as tables. Instead of writing several steps "I have product with :num1 $ price in my cart" we can have one step with multiple values in it.')]),t._v(" "),s("div",{staticClass:"language-gherkin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-gherkin"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("Given")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" have products in my cart"),s("span",{pre:!0,attrs:{class:"token table-head"}},[t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token th variable"}},[t._v(" name ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token th variable"}},[t._v(" category ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token th variable"}},[t._v(" price ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")])]),s("span",{pre:!0,attrs:{class:"token table-body"}},[t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" Harry Potter ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" Books ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" 5 ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" iPhone 5 ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" Smartphones ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" 1200 ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" Nuclear Bomb ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" Weapons ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" 100000 ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")])]),t._v("\n")])])]),s("p",[t._v("Tables are the recommended way to pass arrays into test scenarios.\nInside a step definition data is stored in argument passed as "),s("code",[t._v("DataTable")]),t._v(" JavaScript object.\nYou can iterate on it like this:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Given")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I have products in my cart'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("table")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// eslint-disable-line")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" id "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" table"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("continue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// skip a header of a table")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// go by row cells")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" cells "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" table"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("rows"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("cells"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// take values")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" cells"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" category "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" cells"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" price "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" cells"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("You can also use the "),s("code",[t._v("parse()")]),t._v(" method to obtain an object that allow you to get a simple version of the table parsed by column or row, with header (or not):")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("raw()")]),t._v(" - returns the table as a 2-D array")]),t._v(" "),s("li",[s("code",[t._v("rows()")]),t._v(" - returns the table as a 2-D array, without the first row")]),t._v(" "),s("li",[s("code",[t._v("hashes()")]),t._v(" - returns an array of objects where each row is converted to an object (column header is the key)")]),t._v(" "),s("li",[s("code",[t._v("rowsHash()")]),t._v(" - returns an object where each row corresponds to an entry(first column is the key, second column is the value)")]),t._v(" "),s("li",[s("code",[t._v("transpose()")]),t._v(" - transpose the data, returns nothing. To work with the transposed table use the methods above.")])]),t._v(" "),s("p",[t._v("If we use hashes() with the previous example :")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Given")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I have products in my cart'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("table")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// eslint-disable-line")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//parse the table by header")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" tableByHeader "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" table"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("parse")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("hashes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" row "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("of")]),t._v(" tableByHeader"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// take values")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" category "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("category"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" price "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" row"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("price"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Examples of tables using:")]),t._v(" "),s("div",{staticClass:"language-gherkin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-gherkin"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("Given")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" have a short employees card"),s("span",{pre:!0,attrs:{class:"token table-head"}},[t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token th variable"}},[t._v(" Harry ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token th variable"}},[t._v(" Potter ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")])]),s("span",{pre:!0,attrs:{class:"token table-body"}},[t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" Chuck ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" Norris ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")])]),t._v("\n")])])]),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" DataTableArgument "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'codeceptjs'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Given")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I have a short employees card'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("table")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" dataTableArgument "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DataTableArgument")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("table"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" raw "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" dataTableArgument"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("raw")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// row = [['Harry', 'Potter'], ['Chuck', 'Norris']]")]),t._v("\n dataTableArgument"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("transpose")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" transposedRaw "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" dataTableArgument"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("raw")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// transposedRaw = [['Harry', 'Chuck'], ['Potter', 'Norris']];")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("div",{staticClass:"language-gherkin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-gherkin"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("Given")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" have an employee card"),s("span",{pre:!0,attrs:{class:"token table-head"}},[t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token th variable"}},[t._v(" name ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token th variable"}},[t._v(" surname ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token th variable"}},[t._v(" position ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")])]),s("span",{pre:!0,attrs:{class:"token table-body"}},[t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" Harry ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" Potter ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" Seeker ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")])]),t._v("\n")])])]),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" DataTableArgument "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'codeceptjs'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Given")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I have an employee card'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("table")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" dataTableArgument "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DataTableArgument")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("table"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" hashes "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" dataTableArgument"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("hashes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// hashes = [{ name: 'Harry', surname: 'Potter', position: 'Seeker' }];")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" rows "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" dataTableArgument"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("rows")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// rows = [['Harry', 'Potter', Seeker]];")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("div",{staticClass:"language-gherkin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-gherkin"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("Given")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" have a formatted employee card"),s("span",{pre:!0,attrs:{class:"token table-head"}},[t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token th variable"}},[t._v(" name ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token th variable"}},[t._v(" Harry ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")])]),s("span",{pre:!0,attrs:{class:"token table-body"}},[t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" surname ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" Potter ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" position ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" Seeker ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")])]),t._v("\n")])])]),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" DataTableArgument "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'codeceptjs'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Given")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I have a formatted employee card'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("table")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" dataTableArgument "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DataTableArgument")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("table"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" rawHash "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" dataTableArgument"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("rowsHash")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// rawHash = { name: 'Harry', surname: 'Potter', position: 'Seeker' };")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"examples"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#examples"}},[t._v("#")]),t._v(" Examples")]),t._v(" "),s("p",[t._v("In case scenarios represent the same logic but differ on data, we can use "),s("em",[t._v("Scenario Outline")]),t._v(" to provide different examples for the same behavior. Scenario outline is just like a basic scenario with some values replaced with placeholders, which are filled from a table. Each set of values is executed as a different test.")]),t._v(" "),s("div",{staticClass:"language-gherkin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-gherkin"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token scenario"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("Scenario Outline:")]),s("span",{pre:!0,attrs:{class:"token important"}},[t._v(" order discount")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("Given")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" have product with price "),s("span",{pre:!0,attrs:{class:"token outline variable"}},[t._v("")]),t._v("$ in my cart\n "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("And")]),t._v(" discount for orders greater than $20 is 10 %\n "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("When")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" go to checkout\n "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("Then")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" should see overall price is "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"'),s("span",{pre:!0,attrs:{class:"token outline variable"}},[t._v("")]),t._v('"')]),t._v(" $\n\n "),s("span",{pre:!0,attrs:{class:"token scenario"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("Examples:")]),s("span",{pre:!0,attrs:{class:"token important"}})]),s("span",{pre:!0,attrs:{class:"token table-head"}},[t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token th variable"}},[t._v(" price ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token th variable"}},[t._v(" total ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")])]),s("span",{pre:!0,attrs:{class:"token table-body"}},[t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" 10 ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" 10 ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" 20 ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" 20 ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" 21 ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" 18.9 ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" 30 ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" 27 ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" 50 ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" 45 ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")])]),t._v("\n")])])]),s("p",[t._v("It might be the case that the same column value needs to be utilized multiple times in the same step, that also can be possible with scenario outline.")]),t._v(" "),s("div",{staticClass:"language-gherkin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-gherkin"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token scenario"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("Scenario Outline:")]),s("span",{pre:!0,attrs:{class:"token important"}},[t._v(" check parameter substitution")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("Given")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" have a defined step\n "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("When")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" see "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"'),s("span",{pre:!0,attrs:{class:"token outline variable"}},[t._v("")]),t._v('"')]),t._v(" text and "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"'),s("span",{pre:!0,attrs:{class:"token outline variable"}},[t._v("")]),t._v('"')]),t._v(" is not "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"xyz"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token scenario"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("Examples:")]),s("span",{pre:!0,attrs:{class:"token important"}})]),s("span",{pre:!0,attrs:{class:"token table-head"}},[t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token th variable"}},[t._v(" text ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")])]),s("span",{pre:!0,attrs:{class:"token table-body"}},[t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")]),s("span",{pre:!0,attrs:{class:"token td string"}},[t._v(" Google ")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("|")])]),t._v("\n\n")])])]),s("h3",{attrs:{id:"long-strings"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#long-strings"}},[t._v("#")]),t._v(" Long Strings")]),t._v(" "),s("p",[t._v("Text values inside a scenarios can be set inside a "),s("code",[t._v('"""')]),t._v(" block:")]),t._v(" "),s("div",{staticClass:"language-gherkin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-gherkin"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("Then")]),t._v(" i see in file "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"codecept.json"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token pystring string"}},[t._v('"""\n{\n "output": "./output",\n "helpers": {\n "Puppeteer": {\n "url": "http://localhost",\n "restart": true,\n "windowSize": "1600x1200"\n }\n"""')]),t._v("\n")])])]),s("p",[t._v("This string can be accessed inside a "),s("code",[t._v("content")]),t._v(" property of a last argument:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Then")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Then i see in file {string}'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" text")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// file is a value of {string} from a title")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" fileContent "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" fs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("readFileSync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("file"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toString")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n fileContent"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("should"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("include")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("text"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("content"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// text.content is a value")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"tags"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#tags"}},[t._v("#")]),t._v(" Tags")]),t._v(" "),s("p",[t._v("Gherkin scenarios and features can contain tags marked with "),s("code",[t._v("@")]),t._v(". Tags are appended to feature titles so you can easily filter by them when running tests:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("npx codeceptjs run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--grep")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"@important"')]),t._v("\n")])])]),s("p",[t._v("Tag should be placed before "),s("em",[t._v("Scenario:")]),t._v(" or before "),s("em",[t._v("Feature:")]),t._v(" keyword. In the last case all scenarios of that feature will be added to corresponding group.")]),t._v(" "),s("h3",{attrs:{id:"custom-types"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#custom-types"}},[t._v("#")]),t._v(" Custom types")]),t._v(" "),s("p",[t._v("If you need parameter text in more advanced way, and you like using "),s("a",{attrs:{href:"https://github.com/cucumber/cucumber-expressions#readme",target:"_blank",rel:"noopener noreferrer"}},[t._v("Cucumber expressions"),s("OutboundLink")],1),t._v(" better that regular expressions, use "),s("code",[t._v("DefineParameterType")]),t._v(" function. You can extend Cucumber Expressions, so they automatically convert output parameters to your own types or transforms the match from the regexp.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("DefineParameterType")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'popup_type'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("regexp")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token regex"}},[s("span",{pre:!0,attrs:{class:"token regex-delimiter"}},[t._v("/")]),s("span",{pre:!0,attrs:{class:"token regex-source language-regex"}},[t._v("critical|non-critical")]),s("span",{pre:!0,attrs:{class:"token regex-delimiter"}},[t._v("/")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("transformer")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("match")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" match "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'critical'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("?")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'[class$=\"error\"]'")]),t._v(" \n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'[class$=\"warning\"]'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Given")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I see {popup_type} popup'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("popup")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("popup"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("div",{staticClass:"language-gherkin extra-class"},[s("pre",{pre:!0,attrs:{class:"language-gherkin"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token scenario"}},[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("Scenario:")]),s("span",{pre:!0,attrs:{class:"token important"}},[t._v(" Display error message if user doesn't have permissions")])]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("Given")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" on "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Main"')]),t._v(" page without permissons\n "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("Then")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" see error popup\n")])])]),s("h4",{attrs:{id:"parameters"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#parameters"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("name")]),t._v(" "),s("strong",[t._v("[string]")]),t._v(" The name the parameter type will be recognised by in output parameters.")]),t._v(" "),s("li",[s("code",[t._v("regexp")]),t._v(" "),s("strong",[t._v("([string] | [RegExp])")]),t._v(" A regexp that will match the parameter. May include capture groups.")]),t._v(" "),s("li",[s("code",[t._v("transformer")]),t._v(" "),s("strong",[t._v("[function]")]),t._v(" A function or method that transforms the match from the regexp.")]),t._v(" "),s("li",[s("code",[t._v("useForSnippets")]),t._v(" "),s("strong",[t._v("[boolean]")]),t._v(" Defaults to "),s("code",[t._v("true")]),t._v(". That means this parameter type will be used to generate snippets for undefined steps.")]),t._v(" "),s("li",[s("code",[t._v("preferForRegexpMatch")]),t._v(" "),s("strong",[t._v("[boolean]")]),t._v(" Defaults to "),s("code",[t._v("false")]),t._v(". Set to true if you have step definitions that use regular expressions, and you want this parameter type to take precedence over others during a match.")])]),t._v(" "),s("h2",{attrs:{id:"configuration"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#configuration"}},[t._v("#")]),t._v(" Configuration")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("gherkin")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("features")]),t._v(" - path to feature files, or an array of feature file paths")]),t._v(" "),s("li",[s("code",[t._v("steps")]),t._v(" - array of files with step definitions")]),t._v(" "),s("li",[s("code",[t._v("avoidDuplicateSteps")]),t._v(" - attempts to avoid duplicate step definitions by shallow compare")])])])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"gherkin"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"features"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./features/*.feature"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"steps"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./step_definitions/steps.js"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n")])])]),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"gherkin"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"features"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./features/*.feature"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./features/api_features/*.feature"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"steps"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./step_definitions/steps.js"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n")])])]),s("h2",{attrs:{id:"before"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#before"}},[t._v("#")]),t._v(" Before")]),t._v(" "),s("p",[t._v("You can set up some before hooks inside step definition files. Use "),s("code",[t._v("Before")]),t._v(" function to do that.\nThis function receives current test as a parameter, so you can apply additional configuration to it.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside step_definitions")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Before")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("test")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// perform your code")]),t._v("\n test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("retries")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// retry test 3 times")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("This can be used to keep state between steps:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside step_definitions")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Before")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n state "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Given")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'have a user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("user "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("have")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("When")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I open account page'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("/user/")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("state"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("user"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("slug"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("h2",{attrs:{id:"after"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#after"}},[t._v("#")]),t._v(" After")]),t._v(" "),s("p",[t._v("Similarly to "),s("code",[t._v("Before")]),t._v(" you can use "),s("code",[t._v("After")]),t._v(" and "),s("code",[t._v("Fail")]),t._v(" inside a scenario. "),s("code",[t._v("Fail")]),t._v(" hook is activated on failure and receive two parameters: "),s("code",[t._v("test")]),t._v(" and current "),s("code",[t._v("error")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("After")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" someService"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cleanup")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Fail")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("test"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" err")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// test didn't")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Failed with'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" err"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("pause")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"tests-vs-features"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#tests-vs-features"}},[t._v("#")]),t._v(" Tests vs Features")]),t._v(" "),s("p",[t._v("It is common to think that BDD scenario is equal to test. But it's actually not. Not every test should be described as a feature. Not every test is written to test real business value. For instance, regression tests or negative scenario tests are not bringing any value to business. Business analysts don't care about scenario reproducing bug #13, or what error message is displayed when user tries to enter wrong password on login screen. Writing all the tests inside a feature files creates informational overflow.")]),t._v(" "),s("p",[t._v("In CodeceptJS, you can combine tests written in Gherkin format with classical acceptance tests. This way you can keep your feature files compact with minimal set of scenarios, and write regular tests to cover all cases. Please note, feature files will be executed before tests.")]),t._v(" "),s("p",[t._v("To run only features use "),s("code",[t._v("--features")]),t._v(" option:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run --features\n")])])]),s("p",[t._v("You can run a specific feature file by its filename or by grepping by name or tag.")]),t._v(" "),s("p",[t._v("To run only tests without features use "),s("code",[t._v("--tests")]),t._v(" option:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run --tests\n")])])])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/37.bac110ba.js b/assets/js/37.bac110ba.js new file mode 100644 index 00000000..a07b025d --- /dev/null +++ b/assets/js/37.bac110ba.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[37],{337:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"best-practices"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#best-practices"}},[t._v("#")]),t._v(" Best Practices")]),t._v(" "),s("h2",{attrs:{id:"focus-on-readability"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#focus-on-readability"}},[t._v("#")]),t._v(" Focus on Readability")]),t._v(" "),s("p",[t._v("In CodeceptJS we encourage users to follow semantic elements on page while writing tests.\nInstead of CSS/XPath locators try to stick to visible keywords on page.")]),t._v(" "),s("p",[t._v("Take a look into the next example:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// it's fine but...")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("css")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'nav.user .user-login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// can be better")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'nav.user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("If we replace raw CSS selector with a button title we can improve readability of such test.\nEven if the text on the button changes, it's much easier to update it.")]),t._v(" "),s("blockquote",[s("p",[t._v("If your code goes beyond using "),s("code",[t._v("I")]),t._v(" object or page objects, you are probably doing something wrong.")])]),t._v(" "),s("p",[t._v("When it's hard to match text to element we recommend using "),s("a",{attrs:{href:"/locators#locator-builder"}},[t._v("locator builder")]),t._v(". It allows to build complex locators via fluent API.\nSo if you want to click an element which is not a button or a link and use its text you can use "),s("code",[t._v("locate()")]),t._v(" to build a readable locator:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// clicks element Click me')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("locate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.button'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("withText")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Click me'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"short-cuts"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#short-cuts"}},[t._v("#")]),t._v(" Short Cuts")]),t._v(" "),s("p",[t._v("To write simpler and effective tests we encourage to use short cuts.\nMake test be focused on one feature and try to simplify everything that is not related directly to test.")]),t._v(" "),s("ul",[s("li",[t._v("If data is required for a test, try to create that data via API. See how to do it in "),s("a",{attrs:{href:"/data"}},[t._v("Data Management")]),t._v(" chapter.")]),t._v(" "),s("li",[t._v("If user login is required, use "),s("a",{attrs:{href:"/plugins#autoLogin"}},[t._v("autoLogin plugin")]),t._v(" instead of putting login steps inside a test.")]),t._v(" "),s("li",[t._v("Break a long test into few. Long test can be fragile and complicated to follow and update.")]),t._v(" "),s("li",[t._v("Use "),s("a",{attrs:{href:"/pageobjects"}},[t._v("custom steps and page objects")]),t._v(" to hide steps which are not relevant to current test.")])]),t._v(" "),s("p",[t._v("Make test as simple as:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'editing a metric'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" loginAs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" metricPage "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// login via autoLogin")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("loginAs")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'admin'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create data with ApiDataFactory")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" metric "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("have")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'metric'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'memory'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("duration")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'day'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// use page object to open a page")]),t._v("\n metricPage"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("open")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("metric"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Edit'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Editing Metric'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// using a custom step")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("selectFromDropdown")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'duration'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'week'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Save'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Duration: Week'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.summary'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h2",{attrs:{id:"locators"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#locators"}},[t._v("#")]),t._v(" Locators")]),t._v(" "),s("ul",[s("li",[t._v("If you don't use multi-lingual website or you don't update texts often it is OK to click on links by their texts or match fields by their placeholders.")]),t._v(" "),s("li",[t._v("If you don't want to rely on guessing locators, specify them manually with "),s("code",[t._v("{ css: 'button' }")]),t._v(" or "),s("code",[t._v("{ xpath: '//button' }")]),t._v(". We call them strict locators. Those locators will be faster but less readable.")]),t._v(" "),s("li",[t._v("Even better if you have a convention on active elements with special attributes like "),s("code",[t._v("data-test")]),t._v(" or "),s("code",[t._v("data-qa")]),t._v(". Use "),s("code",[t._v("customLocator")]),t._v(" plugin to easily add them to tests.")]),t._v(" "),s("li",[t._v("Keep tests readable which will make them maintainable.")])]),t._v(" "),s("h2",{attrs:{id:"page-objects"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#page-objects"}},[t._v("#")]),t._v(" Page Objects")]),t._v(" "),s("p",[t._v("When a project is growing and more and more tests are required, it's time to think about reusing test code across the tests. Some common actions should be moved from tests to other files so to be accessible from different tests.")]),t._v(" "),s("p",[t._v("Here is a recommended strategy what to store where:")]),t._v(" "),s("ul",[s("li",[t._v("Move site-wide actions into an "),s("strong",[t._v("Actor")]),t._v(" file ("),s("code",[t._v("custom_steps.js")]),t._v(" file). Such actions like "),s("code",[t._v("login")]),t._v(", using site-wide common controls, like drop-downs, rich text editors, calendars.")]),t._v(" "),s("li",[t._v("Move page-based actions and selectors into "),s("strong",[t._v("Page Object")]),t._v(". All activities made on that page can go into methods of page object. If you test Single Page Application a PageObject should represent a screen of your application.")]),t._v(" "),s("li",[t._v("When site-wide widgets are used, interactions with them should be placed in "),s("strong",[t._v("Page Fragments")]),t._v(". This should be applied to global navigation, modals, widgets.")]),t._v(" "),s("li",[t._v("A custom action that requires some low-level driver access, should be placed into a "),s("strong",[t._v("Helper")]),t._v(". For instance, database connections, complex mouse actions, email testing, filesystem, services access.")])]),t._v(" "),s("blockquote",[s("p",[s("a",{attrs:{href:"/pageobjects"}},[t._v("Learn more")]),t._v(" about different refactoring options")])]),t._v(" "),s("p",[t._v("However, it's recommended to not overengineer and keep tests simple. If a test code doesn't require reusage at this point it should not be transformed to use page objects.")]),t._v(" "),s("ul",[s("li",[t._v("use page objects to store common actions")]),t._v(" "),s("li",[t._v("don't make page objects for every page! Only for pages shared across different tests and suites.")]),t._v(" "),s("li",[t._v("use classes for page objects, this allows inheritace. Export instance of that classes.")]),t._v(" "),s("li",[t._v("if a page object is focused around a form with multiple fields in it, use a flexible set of arguments in it:")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CheckoutForm")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillBillingInformation")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("data "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// take data in a flexible format")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// iterate over fields to fill them all")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" key "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("of")]),t._v(" Object"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("keys")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("key"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// like this one")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nmodule"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("exports "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("CheckoutForm")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmodule"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("exports"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("CheckoutForm "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" CheckoutForm"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// for inheritance")]),t._v("\n")])])]),s("ul",[s("li",[t._v("for components that are repeated accross a website (widgets) but don't belong to any page, use component objects. They are the same as page objects but focused only aroung one element:")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DropDownComponent")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("selectFirstItem")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("locator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#dropdown-items li'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("selectItemByName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("locator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" name")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("locate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'li'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("withText")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#dropdown-items'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ul",[s("li",[t._v("another good example is datepicker component:")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("inject")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/**\n * Calendar works\n */")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DatePicker")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("selectToday")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("locator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.currentDate'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.date-picker'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("selectInNextMonth")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" date "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'15'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'show next month'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.date-picker'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("date"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.date-picker'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n\nmodule"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("exports "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DatePicker")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nmodule"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("exports"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("DatePicker "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" DatePicker"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// for inheritance")]),t._v("\n")])])]),s("h2",{attrs:{id:"configuration"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#configuration"}},[t._v("#")]),t._v(" Configuration")]),t._v(" "),s("ul",[s("li",[t._v("create multiple config files for different setups/enrionments:\n"),s("ul",[s("li",[s("code",[t._v("codecept.conf.js")]),t._v(" - default one")]),t._v(" "),s("li",[s("code",[t._v("codecept.ci.conf.js")]),t._v(" - for CI")]),t._v(" "),s("li",[s("code",[t._v("codecept.windows.conf.js")]),t._v(" - for Windows, etc")])])]),t._v(" "),s("li",[t._v("use "),s("code",[t._v(".env")]),t._v(" files and dotenv package to load sensitive data")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'dotenv'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("path")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.env'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ul",[s("li",[t._v("move similar parts in those configs by moving them to modules and putting them to "),s("code",[t._v("config")]),t._v(" dir")]),t._v(" "),s("li",[t._v("when you need to load lots of page objects/components, you can get components/pageobjects file declaring them:")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside config/components.js")]),t._v("\nmodule"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("exports "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("DatePicker")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./components/datePicker"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Dropdown")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./components/dropdown"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("include them like this:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("include")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./steps_file'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./config/pages'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// require POs and DOs for module")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./config/components'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// require all components")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),s("ul",[s("li",[t._v("move long helpers configuration into "),s("code",[t._v("config/plugins.js")]),t._v(" and export them")]),t._v(" "),s("li",[t._v("move long configuration into "),s("code",[t._v("config/plugins.js")]),t._v(" and export them")]),t._v(" "),s("li",[t._v("inside config files import the exact helpers or plugins needed for this setup & environment")]),t._v(" "),s("li",[t._v("to pass in data from config to a test use a container:")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside codecept conf file")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("bootstrap")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n codeceptjs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("container"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("append")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("testUser")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("email")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'test@test.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("password")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'123456'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// now `testUser` can be injected into a test")]),t._v("\n")])])]),s("ul",[s("li",[t._v("(alternatively) if you have more test data to pass into tests, create a separate file for them and import them similarly to page object:")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("include")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("testData")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./config/testData'")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("ul",[s("li",[t._v(".env / different configs / different test data allows you to get configs for multiple environments")])]),t._v(" "),s("h2",{attrs:{id:"data-access-objects"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#data-access-objects"}},[t._v("#")]),t._v(" Data Access Objects")]),t._v(" "),s("ul",[s("li",[t._v("Concept is similar to page objects but Data access objects can act like factories or data providers for tests")]),t._v(" "),s("li",[t._v("Data Objects require REST or GraphQL helpers to be enabled for data interaction")]),t._v(" "),s("li",[t._v("When you need to customize access to API and go beyond what ApiDataFactory provides, implement DAO:")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" faker "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@faker-js/faker'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("inject")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" output "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'codeceptjs'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InterfaceData")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getLanguages")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" data "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendGetRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/languages'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" records "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n output"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("debug")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("Languages ")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("records"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("r")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" r"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("language"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" records"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("getUsername")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" faker"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("user"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nmodule"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("exports "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("InterfaceData")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/38.fad050cf.js b/assets/js/38.fad050cf.js new file mode 100644 index 00000000..1da8c437 --- /dev/null +++ b/assets/js/38.fad050cf.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[38],{338:function(e,t,o){"use strict";o.r(t);var n=o(14),r=Object(n.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"books-posts"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#books-posts"}},[e._v("#")]),e._v(" Books & Posts")]),e._v(" "),t("blockquote",[t("p",[e._v("Add your own books or posts to our "),t("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/wiki/Books-&-Posts",target:"_blank",rel:"noopener noreferrer"}},[e._v("Wiki Page"),t("OutboundLink")],1)])]),e._v(" "),t("h3",{attrs:{id:"practical-end-2-end-testing-with-codeceptjs"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#practical-end-2-end-testing-with-codeceptjs"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://leanpub.com/codeceptjs/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Practical End 2 End Testing with CodeceptJS"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("A book by "),t("strong",[e._v("Paul Vincent Beigang")])]),e._v(" "),t("p",[t("a",{attrs:{href:"https://leanpub.com/codeceptjs/",target:"_blank",rel:"noopener noreferrer"}},[t("img",{attrs:{src:"https://user-images.githubusercontent.com/220264/58870454-e2e8ce80-86c8-11e9-868e-7deefdde47ce.png",alt:""}}),t("OutboundLink")],1)]),e._v(" "),t("h4",{attrs:{id:"contents"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#contents"}},[e._v("#")]),e._v(" Contents:")]),e._v(" "),t("ol",[t("li",[e._v("Preparation for End 2 End Testing with CodeceptJS")]),e._v(" "),t("li",[e._v("Setup CodeceptJS with WebdriverIO")]),e._v(" "),t("li",[e._v("Create Your First CodeceptJS Test")]),e._v(" "),t("li",[e._v("Run Your First CodeceptJS Test Locally")]),e._v(" "),t("li",[e._v("Run Test on BrowserStack Against with the Safari Browser")]),e._v(" "),t("li",[e._v("How to Debug & Fix a Failing E2E Test")]),e._v(" "),t("li",[e._v("Run a CodeceptJS Test in GitLab´s Continuous Integration (CI) Environment")]),e._v(" "),t("li",[e._v("Delicious Test Reports With Allure")])]),e._v(" "),t("h3",{attrs:{id:"posts"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#posts"}},[e._v("#")]),e._v(" Posts")]),e._v(" "),t("p",[e._v("A list of good educational posts about CodeceptJS")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://medium.com/@dan.ryan.emmons/qa-automation-from-zero-to-hero-with-codeceptjs-end-to-end-testing-719db9d6ff5c",target:"_blank",rel:"noopener noreferrer"}},[e._v("QA Automation From Zero-to-Hero with CodeceptJS End-to-End Testing"),t("OutboundLink")],1),e._v(" by Dan Emmons")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://hackernoon.com/effective-end-2-end-testing-in-javascript-with-codeceptjs-37c8d7d6a928",target:"_blank",rel:"noopener noreferrer"}},[e._v("Effective End2End Tests with CodeceptJS"),t("OutboundLink")],1),e._v(" by @davertmik")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://medium.com/@successivetech/codeceptjs-skeleton-9ba86d3b45ec",target:"_blank",rel:"noopener noreferrer"}},[e._v("Customizing CodeceptJS Skeleton"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://hackernoon.com/running-end-to-end-tests-as-google-cloud-functions-f5e34ffc3984",target:"_blank",rel:"noopener noreferrer"}},[e._v("Running End to End tests as Google Cloud Functions"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.monterail.com/blog/end-to-end-testing-with-codeceptjs",target:"_blank",rel:"noopener noreferrer"}},[e._v("End-To-End Testing With CodeceptJS"),t("OutboundLink")],1),e._v(" by Piotr Michalski")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://medium.com/@garrettvorce/getting-started-with-selenium-and-codeceptjs-c0698e8df677",target:"_blank",rel:"noopener noreferrer"}},[e._v("Getting started with CodeceptJS and Selenium WebDriver"),t("OutboundLink")],1)])])])}),[],!1,null,null,null);t.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/39.e8d1e2f0.js b/assets/js/39.e8d1e2f0.js new file mode 100644 index 00000000..374faf62 --- /dev/null +++ b/assets/js/39.e8d1e2f0.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[39],{339:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"bootstrap"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#bootstrap"}},[t._v("#")]),t._v(" Bootstrap")]),t._v(" "),s("p",[t._v("In case you need to execute arbitrary code before or after the tests,\nyou can use the "),s("code",[t._v("bootstrap")]),t._v(" and "),s("code",[t._v("teardown")]),t._v(" config. Use it to start and stop a webserver, Selenium, etc.")]),t._v(" "),s("p",[t._v("When using the "),s("a",{attrs:{href:"/parallel"}},[t._v("parallel execution")]),t._v(" mode, there are two additional hooks available; "),s("code",[t._v("bootstrapAll")]),t._v(" and "),s("code",[t._v("teardownAll")]),t._v(". See "),s("a",{attrs:{href:"#bootstrapall-teardownall"}},[t._v("bootstrapAll & teardownAll")]),t._v(" for more information.")]),t._v(" "),s("blockquote",[s("p",[t._v("⚠ In CodeceptJS 2 bootstrap could be set as a function with "),s("code",[t._v("done")]),t._v(" parameter. This way of handling async function was replaced with native async functions in CodeceptJS 3.")])]),t._v(" "),s("h3",{attrs:{id:"example-bootstrap-teardown"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-bootstrap-teardown"}},[t._v("#")]),t._v(" Example: Bootstrap & Teardown")]),t._v(" "),s("p",[t._v("If you are using JavaScript-style config "),s("code",[t._v("codecept.conf.js")]),t._v(", bootstrap and teardown functions can be placed inside of it:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" server "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./app_server'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nexports"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("tests")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./*_test.js"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// adding bootstrap/teardown")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bootstrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" server"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("launch")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("teardown")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" server"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("stop")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// other config options")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])]),s("h2",{attrs:{id:"bootstrapall-teardownall"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#bootstrapall-teardownall"}},[t._v("#")]),t._v(" BootstrapAll & TeardownAll")]),t._v(" "),s("p",[t._v("There are two additional hooks for "),s("a",{attrs:{href:"/parallel"}},[t._v("parallel execution")]),t._v(" in "),s("code",[t._v("run-multiple")]),t._v(" or "),s("code",[t._v("run-workers")]),t._v(" commands.")]),t._v(" "),s("p",[t._v("These hooks are only called in the parent process. Before child processes start ("),s("code",[t._v("bootstrapAll")]),t._v(") and after all of runs have finished ("),s("code",[t._v("teardownAll")]),t._v("). Each worker process will call "),s("code",[t._v("bootstrap")]),t._v(" & "),s("code",[t._v("teardown")]),t._v(" in their own process.")]),t._v(" "),s("p",[t._v("For example, when you run tests in 2 workers using the following command:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run-workers 2\n")])])]),s("p",[t._v("First, "),s("code",[t._v("bootstrapAll")]),t._v(" is called. Then two "),s("code",[t._v("bootstrap")]),t._v(" runs in each of workers. Then tests in worker #1 ends and "),s("code",[t._v("teardown")]),t._v(" is called. Same for worker #2. Finally, "),s("code",[t._v("teardownAll")]),t._v(" runs in the main process.")]),t._v(" "),s("blockquote",[s("p",[t._v("The same behavior is set for "),s("code",[t._v("run-multiple")]),t._v(" command")])]),t._v(" "),s("p",[t._v("The "),s("code",[t._v("bootstrapAll")]),t._v(" and "),s("code",[t._v("teardownAll")]),t._v(" hooks are preferred to use for setting up common logic of tested project: to start the application server or database or to start webdriver's grid.")]),t._v(" "),s("p",[t._v("The "),s("code",[t._v("bootstrap")]),t._v(" and "),s("code",[t._v("teardown")]),t._v(" hooks are used for setting up each testing browser: to create unique "),s("a",{attrs:{href:"/helpers/WebDriver#cloud-providers"}},[t._v("cloud testing server")]),t._v(" connection or to create specific browser-related test data in database (like users with names with browsername in it).")]),t._v(" "),s("h3",{attrs:{id:"example-bootstrapall-teardownall-inside-config"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#example-bootstrapall-teardownall-inside-config"}},[t._v("#")]),t._v(" Example: BootstrapAll & TeardownAll Inside Config")]),t._v(" "),s("p",[t._v("Using JavaScript-style config "),s("code",[t._v("codecept.conf.js")]),t._v(", bootstrapAll and teardownAll functions can be placed inside of it:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" fs "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'fs'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" tempFolder "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" process"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cwd")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/tmpFolder'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nexports"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("tests")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./*_test.js"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// adding bootstrapAll/teardownAll")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bootstrapAll")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n fs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mkdirSync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tempFolder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bootstrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Do some pretty suite setup stuff'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("teardown")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Cool, one of the workers have finished'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("teardownAll")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'All workers have finished running tests so we should clean up the temp folder'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n fs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("rmdirSync")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("tempFolder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// other config options")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"combining-bootstrap-bootstrapall"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#combining-bootstrap-bootstrapall"}},[t._v("#")]),t._v(" Combining Bootstrap & BootstrapAll")]),t._v(" "),s("p",[t._v("It is quite common that you expect that bootstrapAll and bootstrap will do the same thing. If an application server is already started in "),s("code",[t._v("bootstrapAll")]),t._v(" we should not run it again inside "),s("code",[t._v("bootstrap")]),t._v(" for each worker. To avoid code duplication we can run bootstrap script only when we are not inside a worker. And we will use NodeJS "),s("code",[t._v("isMainThread")]),t._v(" Workers API to detect that:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside codecept.conf.js")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// detect if we are in a worker thread")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" isMainThread "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'worker_threads'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("startServer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// implement starting server logic here")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("stopServer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// and stop server too")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n\nexports"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// codeceptjs config goes here")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bootstrapAll")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("startServer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("bootstrap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// start a server only if we are not in worker")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("isMainThread"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("startServer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("teardown")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// start a server only if we are not in worker")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("isMainThread"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("stopServer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("teardownAll")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("stopServer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/4.64d49130.js b/assets/js/4.64d49130.js new file mode 100644 index 00000000..3a903367 --- /dev/null +++ b/assets/js/4.64d49130.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[4,26,29],{242:function(t,e,s){},243:function(t,e,s){},244:function(t,e){t.exports=function(t){return null==t}},245:function(t,e,s){},246:function(t,e,s){},247:function(t,e,s){},248:function(t,e,s){},251:function(t,e,s){"use strict";s.r(e);var i=s(267),a=s(261),n=s(239);function r(t,e){return"group"===e.type&&e.children.some(e=>"group"===e.type?r(t,e):"page"===e.type&&Object(n.e)(t,e.path))}var o={name:"SidebarLinks",components:{SidebarGroup:i.default,SidebarLink:a.default},props:["items","depth","sidebarDepth"],data:()=>({openGroupIndex:0}),created(){this.refreshIndex()},watch:{$route(){this.refreshIndex()}},methods:{refreshIndex(){const t=function(t,e){for(let s=0;s-1&&(this.openGroupIndex=t)},toggleGroup(t){this.openGroupIndex=t===this.openGroupIndex?-1:t},isActive(t){return Object(n.e)(this.$route,t.regularPath)}}},l=s(14),c=Object(l.a)(o,(function(){var t=this,e=t._self._c;return t.items.length?e("ul",{staticClass:"sidebar-links"},t._l(t.items,(function(s,i){return e("li",{key:i},["group"===s.type?e("SidebarGroup",{attrs:{item:s,open:i===t.openGroupIndex,collapsable:s.collapsable||s.collapsible,depth:t.depth},on:{toggle:function(e){return t.toggleGroup(i)}}}):e("SidebarLink",{attrs:{sidebarDepth:t.sidebarDepth,item:s}})],1)})),0):t._e()}),[],!1,null,null,null);e.default=c.exports},255:function(t,e,s){},256:function(t,e,s){"use strict";s(242)},257:function(t,e,s){"use strict";s(243)},258:function(t,e,s){},259:function(t,e,s){},260:function(t,e,s){},261:function(t,e,s){"use strict";s.r(e);var i=s(239);function a(t,e,s,i){return t("router-link",{props:{to:e,activeClass:"",exactActiveClass:""},class:{active:i,"sidebar-link":!0}},s)}function n(t,e,s,r,o,l=1){return!e||l>o?null:t("ul",{class:"sidebar-sub-headers"},e.map(e=>{const c=Object(i.e)(r,s+"#"+e.slug);return t("li",{class:"sidebar-sub-header"},[a(t,s+"#"+e.slug,e.title,c),n(t,e.children,s,r,o,l+1)])}))}var r={functional:!0,props:["item","sidebarDepth"],render(t,{parent:{$page:e,$site:s,$route:r,$themeConfig:o,$themeLocaleConfig:l},props:{item:c,sidebarDepth:u}}){const d=Object(i.e)(r,c.path),p="auto"===c.type?d||c.children.some(t=>Object(i.e)(r,c.basePath+"#"+t.slug)):d,h="external"===c.type?function(t,e,s){return t("a",{attrs:{href:e,target:"_blank",rel:"noopener noreferrer"},class:{"sidebar-link":!0}},[s,t("OutboundLink")])}(t,c.path,c.title||c.path):a(t,c.path,c.title||c.path,p),f=[e.frontmatter.sidebarDepth,u,l.sidebarDepth,o.sidebarDepth,1].find(t=>void 0!==t),b=l.displayAllHeaders||o.displayAllHeaders;if("auto"===c.type)return[h,n(t,c.children,c.basePath,r,f)];if((p||b)&&c.headers&&!i.d.test(c.path)){return[h,n(t,Object(i.c)(c.headers),c.path,r,f)]}return h}},o=(s(256),s(257),s(14)),l=Object(o.a)(r,void 0,void 0,!1,null,"a68ca4e6",null);e.default=l.exports},262:function(t,e,s){"use strict";s(245)},263:function(t,e,s){var i=s(11),a=s(4),n=s(10);t.exports=function(t){return"string"==typeof t||!a(t)&&n(t)&&"[object String]"==i(t)}},264:function(t,e,s){"use strict";s(246)},265:function(t,e,s){"use strict";s(247)},266:function(t,e,s){"use strict";s(248)},267:function(t,e,s){"use strict";s.r(e);var i=s(239),a={name:"SidebarGroup",props:["item","open","collapsable","depth"],components:{DropdownTransition:s(249).default},beforeCreate(){this.$options.components.SidebarLinks=s(251).default},methods:{isActive:i.e}},n=(s(266),s(14)),r=Object(n.a)(a,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"sidebar-group",class:[{collapsable:t.collapsable,"is-sub-group":0!==t.depth},"depth-"+t.depth]},[t.item.path?e("router-link",{staticClass:"sidebar-heading clickable",class:{open:t.open,active:t.isActive(t.$route,t.item.path)},attrs:{to:t.item.path},nativeOn:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"open":""}):t._e()]):e("p",{staticClass:"sidebar-heading",class:{open:t.open},on:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"open":""}):t._e()]),t._v(" "),e("DropdownTransition",[t.open||!t.collapsable?e("SidebarLinks",{staticClass:"sidebar-group-items",attrs:{items:t.item.children,sidebarDepth:t.item.sidebarDepth,depth:t.depth+1}}):t._e()],1)],1)}),[],!1,null,null,null);e.default=r.exports},268:function(t,e,s){"use strict";s.r(e);s(265);var i=s(14),a=Object(i.a)({},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"sidebar"},[e("div",{staticClass:"sidebar-wrapper"},[e("h4",[t._v("More Information")]),t._v(" "),e("p",[e("router-link",{attrs:{to:"/videos"}},[t._v("Videos")])],1),t._v(" "),e("p",[e("router-link",{attrs:{to:"/books"}},[t._v("Books & Posts")])],1),t._v(" "),e("p",[e("router-link",{attrs:{to:"/examples"}},[t._v("Examples")])],1),t._v(" "),t._m(0),t._v(" "),e("hr"),t._v(" "),t._m(1),t._v(" "),t._m(2),t._v(" "),t._m(3),t._v(" "),t._m(4)])])}),[function(){var t=this._self._c;return t("p",[t("a",{attrs:{href:"https://codecept.discourse.group/c/cookbook"}},[this._v("Cookbook →")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://sdclabs.com/codeceptjs?utm_source=codecept.io&utm_medium=right&utm_term=link&utm_campaign=reference"}},[this._v("\n Commercial Services →\n ")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://sdclabs.com/trainings/web-automation-codeceptjs?utm_source=codecept.io&utm_medium=rigth&utm_term=link&utm_campaign=reference"}},[this._v("\n Trainings →\n ")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://testomat.io"}},[this._v("\n Testomat.io →\n ")]),t("br"),this._v(" "),t("small",[t("b",[this._v("Plan your end 2 end tests")]),this._v(", collaborate, synchronize with code & get reports!"),t("br"),this._v("\n Join Testomat.io while it is in beta and get a huge discount!")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://opencollective.com/codeceptjs"}},[this._v("\n Support us via OpenCollective!\n ")])])}],!1,null,"0dc4070a",null);e.default=a.exports},273:function(t,e,s){"use strict";s.r(e);var i=s(244),a=s.n(i),n=s(239),r={name:"PageEdit",computed:{lastUpdated(){return this.$page.lastUpdated},lastUpdatedText(){return"string"==typeof this.$themeLocaleConfig.lastUpdated?this.$themeLocaleConfig.lastUpdated:"string"==typeof this.$site.themeConfig.lastUpdated?this.$site.themeConfig.lastUpdated:"Last Updated"},editLink(){const t=a()(this.$page.frontmatter.editLink)?this.$site.themeConfig.editLinks:this.$page.frontmatter.editLink,{repo:e,docsDir:s="",docsBranch:i="master",docsRepo:n=e}=this.$site.themeConfig;return t&&n&&this.$page.relativePath?this.createEditLink(e,n,s,i,this.$page.relativePath):null},editLinkText(){return this.$themeLocaleConfig.editLinkText||this.$site.themeConfig.editLinkText||"Edit this page"}},methods:{createEditLink(t,e,s,i,a){if(/bitbucket.org/.test(t)){return(n.i.test(e)?e:t).replace(n.a,"")+"/src"+`/${i}/`+(s?s.replace(n.a,"")+"/":"")+a+`?mode=edit&spa=0&at=${i}&fileviewer=file-view-default`}return(n.i.test(e)?e:"https://github.com/"+e).replace(n.a,"")+"/edit"+`/${i}/`+(s?s.replace(n.a,"")+"/":"")+a}}},o=(s(262),s(14)),l=Object(o.a)(r,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"page-edit"},[t.editLink?e("div",{staticClass:"edit-link"},[e("a",{attrs:{href:t.editLink,target:"_blank",rel:"noopener noreferrer"}},[t._v(t._s(t.editLinkText))]),t._v(" "),e("OutboundLink")],1):t._e(),t._v(" "),t.lastUpdated?e("div",{staticClass:"last-updated"},[e("span",{staticClass:"prefix"},[t._v(t._s(t.lastUpdatedText)+":")]),t._v(" "),e("span",{staticClass:"time"},[t._v(t._s(t.lastUpdated))])]):t._e()])}),[],!1,null,null,null);e.default=l.exports},274:function(t,e,s){"use strict";s.r(e);s(89);var i=s(239),a=s(263),n=s.n(a),r=s(244),o=s.n(r),l={name:"PageNav",props:["sidebarItems"],computed:{prev(){return u(c.PREV,this)},next(){return u(c.NEXT,this)}}};const c={NEXT:{resolveLink:function(t,e){return d(t,e,1)},getThemeLinkConfig:({nextLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.next},PREV:{resolveLink:function(t,e){return d(t,e,-1)},getThemeLinkConfig:({prevLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.prev}};function u(t,{$themeConfig:e,$page:s,$route:a,$site:r,sidebarItems:l}){const{resolveLink:c,getThemeLinkConfig:u,getPageLinkConfig:d}=t,p=u(e),h=d(s),f=o()(h)?p:h;return!1===f?void 0:n()(f)?Object(i.k)(r.pages,f,a.path):c(s,l)}function d(t,e,s){const i=[];!function t(e,s){for(let i=0,a=e.length;i({isSidebarOpen:!1}),computed:{shouldShowNavbar(){const{themeConfig:t}=this.$site,{frontmatter:e}=this.$page;return!1!==e.navbar&&!1!==t.navbar&&(this.$title||t.logo||t.repo||t.nav||this.$themeLocaleConfig.nav)},shouldShowSidebar(){const{frontmatter:t}=this.$page;return!t.home&&!1!==t.sidebar&&this.sidebarItems.length},sidebarItems(){return Object(o.l)(this.$page,this.$page.regularPath,this.$site,this.$localePath)},pageClasses(){const t=this.$page.frontmatter.pageClass;return[{"no-navbar":!this.shouldShowNavbar,"sidebar-open":this.isSidebarOpen,"no-sidebar":!this.shouldShowSidebar},t]}},mounted(){this.$router.afterEach(()=>{this.isSidebarOpen=!1})},methods:{toggleSidebar(t){this.isSidebarOpen="boolean"==typeof t?t:!this.isSidebarOpen,this.$emit("toggle-sidebar",this.isSidebarOpen)},onTouchStart(t){this.touchStart={x:t.changedTouches[0].clientX,y:t.changedTouches[0].clientY}},onTouchEnd(t){const e=t.changedTouches[0].clientX-this.touchStart.x,s=t.changedTouches[0].clientY-this.touchStart.y;Math.abs(e)>Math.abs(s)&&Math.abs(e)>40&&(e>0&&this.touchStart.x<=80?this.toggleSidebar(!0):this.toggleSidebar(!1))}}},u=s(14),d=Object(u.a)(c,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"theme-container",class:t.pageClasses,on:{touchstart:t.onTouchStart,touchend:t.onTouchEnd}},[t.shouldShowNavbar?e("Navbar",{on:{"toggle-sidebar":t.toggleSidebar}}):t._e(),t._v(" "),e("Subbar"),t._v(" "),e("div",{staticClass:"sidebar-mask",on:{click:function(e){return t.toggleSidebar(!1)}}}),t._v(" "),e("Sidebar",{attrs:{items:t.sidebarItems},on:{"toggle-sidebar":t.toggleSidebar}},[t._t("sidebar-top"),t._v(" "),t._t("sidebar-bottom")],2),t._v(" "),e("Home")],1)}),[],!1,null,null,null);e.default=d.exports}}]); \ No newline at end of file diff --git a/assets/js/40.f548b3b3.js b/assets/js/40.f548b3b3.js new file mode 100644 index 00000000..c9e4fe93 --- /dev/null +++ b/assets/js/40.f548b3b3.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[40],{343:function(t,e,r){"use strict";r.r(e);var n=r(14),s=Object(n.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"releases"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#releases"}},[t._v("#")]),t._v(" Releases")]),t._v(" "),e("h2",{attrs:{id:"_3-6-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-6-4"}},[t._v("#")]),t._v(" 3.6.4")]),t._v(" "),e("p",[t._v("❤️ Thanks all to those who contributed to make this release! ❤️")]),t._v(" "),e("p",[t._v("🛩️ "),e("em",[t._v("Features")])]),t._v(" "),e("ul",[e("li",[t._v("feat(rest): print curl ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4396",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4396"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/kobenguyent",target:"_blank",rel:"noopener noreferrer"}},[t._v("kobenguyent"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("Config:\n\n...\nREST: {\n ...\n printCurl: true,\n ...\n}\n... \n\n› [CURL Request] curl --location --request POST https://httpbin.org/post -H ...\n")])])]),e("ul",[e("li",[t._v("feat(AI): Generate PageObject, added types, shell improvement ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4319",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4319"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/davert",target:"_blank",rel:"noopener noreferrer"}},[t._v("davert"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[t._v("added "),e("code",[t._v("askForPageObject")]),t._v(" method to generate PageObjects on the fly")]),t._v(" "),e("li",[t._v("improved AI types")]),t._v(" "),e("li",[t._v("interactive shell improved to restore history")])])])]),t._v(" "),e("p",[e("img",{attrs:{src:"https://github.com/codeceptjs/CodeceptJS/assets/220264/12acd2c7-18d1-4105-a24b-84070ec4d393",alt:"Screenshot from 2024-06-17 02-47-37"}})]),t._v(" "),e("p",[t._v("🐛 "),e("em",[t._v("Bug Fixes")])]),t._v(" "),e("ul",[e("li",[t._v("fix(heal): wrong priority ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4394",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4394"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/kobenguyent",target:"_blank",rel:"noopener noreferrer"}},[t._v("kobenguyent"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("📖 "),e("em",[t._v("Documentation")])]),t._v(" "),e("ul",[e("li",[t._v("AI docs improvements")])]),t._v(" "),e("h2",{attrs:{id:"_3-6-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-6-3"}},[t._v("#")]),t._v(" 3.6.3")]),t._v(" "),e("p",[t._v("❤️ Thanks all to those who contributed to make this release! ❤️")]),t._v(" "),e("p",[t._v("🛩️ "),e("em",[t._v("Features")])]),t._v(" "),e("ul",[e("li",[t._v("feat(plugin): coverage with WebDriver - devtools ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4349",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4349"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyent",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyent"),e("OutboundLink")],1)]),t._v(" "),e("img",{attrs:{src:"https://github.com/codeceptjs/CodeceptJS/assets/7845001/a02f0f99-ac78-4d3f-9774-2cb51c688025",alt:"Screenshot 2024-05-16 at 16 49 20"}})])]),t._v(" "),e("p",[t._v("🐛 "),e("em",[t._v("Bug Fixes")])]),t._v(" "),e("ul",[e("li",[t._v("fix(cli): stale process ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4367",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4367"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/Horsty80",target:"_blank",rel:"noopener noreferrer"}},[t._v("Horsty80"),e("OutboundLink")],1)]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://github.com/kobenguyent",target:"_blank",rel:"noopener noreferrer"}},[t._v("kobenguyent"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(runner): screenshot error in beforeSuite/AfterSuite ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4385",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4385"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/kobenguyent",target:"_blank",rel:"noopener noreferrer"}},[t._v("kobenguyent"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(cli): gherkin command init with TypeScript ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4366",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4366"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/andonary",target:"_blank",rel:"noopener noreferrer"}},[t._v("andonary"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(webApi): error message of dontSeeCookie ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4357",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4357"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/a-stankevich",target:"_blank",rel:"noopener noreferrer"}},[t._v("a-stankevich"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("📖 "),e("em",[t._v("Documentation")])]),t._v(" "),e("ul",[e("li",[t._v("fix(doc): Expect helper is not described correctly ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4370",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4370"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/kobenguyent",target:"_blank",rel:"noopener noreferrer"}},[t._v("kobenguyent"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(docs): some strange characters ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4387",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4387"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/kobenguyent",target:"_blank",rel:"noopener noreferrer"}},[t._v("kobenguyent"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: Puppeteer helper doc typo ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4369",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4369"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/yoannfleurydev",target:"_blank",rel:"noopener noreferrer"}},[t._v("yoannfleurydev"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-6-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-6-2"}},[t._v("#")]),t._v(" 3.6.2")]),t._v(" "),e("p",[t._v("❤️ Thanks all to those who contributed to make this release! ❤️")]),t._v(" "),e("p",[t._v("🛩️ "),e("em",[t._v("Features")])]),t._v(" "),e("ul",[e("li",[t._v("feat(REST): support httpAgent conf ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4328",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4328"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyent",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyent"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("Support the httpAgent conf to create the TSL connection via REST helper")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("{\n helpers: {\n REST: {\n endpoint: 'http://site.com/api',\n prettyPrintJson: true,\n httpAgent: {\n key: fs.readFileSync(__dirname + '/path/to/keyfile.key'),\n cert: fs.readFileSync(__dirname + '/path/to/certfile.cert'),\n rejectUnauthorized: false,\n keepAlive: true\n }\n }\n }\n}\n")])])]),e("ul",[e("li",[t._v("feat(wd): screenshots for sessions ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4322",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4322"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyent",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyent"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("Currently only screenshot of the active session is saved, this PR aims to save the screenshot of every session for easy debugging")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("Scenario('should save screenshot for sessions **[WebDriverIO](https://github.com/WebDriverIO)** **[Puppeteer](https://github.com/Puppeteer)** **[Playwright](https://github.com/Playwright)**', async ({ I }) => {\n await I.amOnPage('/form/bug1467');\n await I.saveScreenshot('original.png');\n await I.amOnPage('/');\n await I.saveScreenshot('main_session.png');\n session('john', async () => {\n await I.amOnPage('/form/bug1467');\n event.dispatcher.emit(event.test.failed, this);\n });\n\n const fileName = clearString('should save screenshot for active session **[WebDriverIO](https://github.com/WebDriverIO)** **[Puppeteer](https://github.com/Puppeteer)** **[Playwright](https://github.com/Playwright)**');\n const [original, failed] = await I.getSHA256Digests([\n `${output_dir}/original.png`,\n `${output_dir}/john_${fileName}.failed.png`,\n ]);\n\n // Assert that screenshots of same page in same session are equal\n await I.expectEqual(original, failed);\n\n // Assert that screenshots of sessions are created\n const [main_original, session_failed] = await I.getSHA256Digests([\n `${output_dir}/main_session.png`,\n `${output_dir}/john_${fileName}.failed.png`,\n ]);\n await I.expectNotEqual(main_original, session_failed);\n});\n")])])]),e("p",[e("img",{attrs:{src:"https://github.com/codeceptjs/CodeceptJS/assets/7845001/5dddf85a-ed77-474b-adfd-2f208d3c16a8",alt:"Screenshot 2024-04-29 at 11 07 47"}})]),t._v(" "),e("ul",[e("li",[t._v("feat: locate element with withClassAttr ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4321",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4321"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyent",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyent"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("Find an element with class attribute")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// find div with class contains 'form'")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("locate")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'div'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("withClassAttr")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'text'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[t._v("fix(playwright): set the record video resolution ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4311",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4311"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyent",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyent"),e("OutboundLink")],1)]),t._v("\nYou could now set the recording video resolution")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v(" url: siteUrl,\n windowSize: '300x500',\n show: false,\n restart: true,\n browser: 'chromium',\n trace: true,\n video: true,\n recordVideo: {\n size: {\n width: 400,\n height: 600,\n },\n },\n")])])]),e("p",[t._v("🐛 "),e("em",[t._v("Bug Fixes")])]),t._v(" "),e("ul",[e("li",[t._v("fix: several issues of stepByStep report ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4331",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4331"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyent",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyent"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("📖 "),e("em",[t._v("Documentation")])]),t._v(" "),e("ul",[e("li",[t._v("fix: wrong format docs ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4330",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4330"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyent",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyent"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(docs): wrong method is mentioned ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4320",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4320"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyent",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyent"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: ChatGPT docs - by "),e("strong",[e("a",{attrs:{href:"https://github.com/davert",target:"_blank",rel:"noopener noreferrer"}},[t._v("davert"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-6-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-6-1"}},[t._v("#")]),t._v(" 3.6.1")]),t._v(" "),e("ul",[e("li",[t._v("Fixed regression in interactive pause.")])]),t._v(" "),e("h2",{attrs:{id:"_3-6-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-6-0"}},[t._v("#")]),t._v(" 3.6.0")]),t._v(" "),e("p",[t._v("🛩️ "),e("em",[t._v("Features")])]),t._v(" "),e("ul",[e("li",[t._v("Introduced "),e("a",{attrs:{href:"./heal"}},[t._v("healers")]),t._v(" to improve stability of failed tests. Write functions that can perform actions to fix a failing test:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[t._v("heal"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipe")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'reloadPageIfModalIsNotVisisble'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("steps")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'click'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("fn")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" error"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" step "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// this function will be executed only if test failed with")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// "model is not visible" message')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("error"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("message"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("include")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'modal is not visible'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// we return a function that will refresh a page")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// and tries to perform last step again")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("reloadPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("wait")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" step"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("run")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// if a function succeeds, test continues without an error")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("p",[e("strong",[t._v("Breaking Change")]),t._v(" "),e("strong",[t._v("AI")]),t._v(" features refactored. Read updated "),e("a",{attrs:{href:"./ai"}},[t._v("AI guide")]),t._v(":")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("removed dependency on "),e("code",[t._v("openai")])])]),t._v(" "),e("li",[t._v("added support for "),e("strong",[t._v("Azure OpenAI")]),t._v(", "),e("strong",[t._v("Claude")]),t._v(", "),e("strong",[t._v("Mistal")]),t._v(", or any AI via custom request function")]),t._v(" "),e("li",[e("code",[t._v("--ai")]),t._v(" option added to explicitly enable AI features")]),t._v(" "),e("li",[t._v("heal plugin decoupled from AI to run custom heal recipes")]),t._v(" "),e("li",[t._v("improved healing for async/await scenarios")]),t._v(" "),e("li",[t._v("token limits added")]),t._v(" "),e("li",[t._v("token calculation introduced")]),t._v(" "),e("li",[e("code",[t._v("OpenAI")]),t._v(" helper renamed to "),e("code",[t._v("AI")])])])]),t._v(" "),e("li",[e("p",[t._v("feat(puppeteer): network traffic manipulation. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4263",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4263"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("ul",[e("li",[e("code",[t._v("startRecordingTraffic")])]),t._v(" "),e("li",[e("code",[t._v("grabRecordedNetworkTraffics")])]),t._v(" "),e("li",[e("code",[t._v("flushNetworkTraffics")])]),t._v(" "),e("li",[e("code",[t._v("stopRecordingTraffic")])]),t._v(" "),e("li",[e("code",[t._v("seeTraffic")])]),t._v(" "),e("li",[e("code",[t._v("dontSeeTraffic")])])])]),t._v(" "),e("li",[e("p",[t._v("feat(Puppeteer): recording WS messages. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4264",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4264"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])])]),t._v(" "),e("p",[t._v("Recording WS messages:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v(" I.startRecordingWebSocketMessages();\n I.amOnPage('https://websocketstest.com/');\n I.waitForText('Work for You!');\n const wsMessages = I.grabWebSocketMessages();\n expect(wsMessages.length).to.greaterThan(0);\n")])])]),e("p",[t._v("flushing WS messages:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v(" I.startRecordingWebSocketMessages();\n I.amOnPage('https://websocketstest.com/');\n I.waitForText('Work for You!');\n I.flushWebSocketMessages();\n const wsMessages = I.grabWebSocketMessages();\n expect(wsMessages.length).to.equal(0);\n")])])]),e("p",[t._v("Examples:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// recording traffics and verify the traffic")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("startRecordingTraffic")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://codecept.io/'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeTraffic")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'traffics'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://codecept.io/img/companies/BC_LogoScreen_C.jpg'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// check the traffic with advanced params")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://openai.com/blog/chatgpt'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("startRecordingTraffic")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeTraffic")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'sentry event'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://images.openai.com/blob/cf717bdb-0c8c-428a-b82b-3c3add87a600'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("parameters")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1919'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1138'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Introduce the playwright locator: "),e("code",[t._v("_react")]),t._v(", "),e("code",[t._v("_vue")]),t._v(", "),e("code",[t._v("data-testid")]),t._v(" attribute. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4255",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4255"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("Scenario('using playwright locator **[Playwright](https://github.com/Playwright)**', () => {\n I.amOnPage('https://codecept.io/test-react-calculator/');\n I.click('7');\n I.click({ pw: '_react=t[name = \"=\"]' });\n I.seeElement({ pw: '_react=t[value = \"7\"]' });\n I.click({ pw: '_react=t[name = \"+\"]' });\n I.click({ pw: '_react=t[name = \"3\"]' });\n I.click({ pw: '_react=t[name = \"=\"]' });\n I.seeElement({ pw: '_react=t[value = \"10\"]' });\n});\n")])])]),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("Scenario('using playwright data-testid attribute **[Playwright](https://github.com/Playwright)**', () => {\n I.amOnPage('/');\n const webElements = await I.grabWebElements({ pw: '[data-testid=\"welcome\"]' });\n assert.equal(webElements[0]._selector, '[data-testid=\"welcome\"] >> nth=0');\n assert.equal(webElements.length, 1);\n});\n")])])]),e("ul",[e("li",[t._v("feat(puppeteer): mockRoute support. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4262",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4262"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("Network requests & responses can be mocked and modified. Use "),e("code",[t._v("mockRoute")]),t._v(" which strictly follows "),e("a",{attrs:{href:"https://pptr.dev/next/api/puppeteer.page.setrequestinterception",target:"_blank",rel:"noopener noreferrer"}},[t._v("Puppeteer's setRequestInterception API"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("I.mockRoute('https://reqres.in/api/comments/1', request => {\n request.respond({\n status: 200,\n headers: { 'Access-Control-Allow-Origin': '*' },\n contentType: 'application/json',\n body: '{\"name\": \"this was mocked\" }',\n });\n})\n")])])]),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("I.mockRoute('**/*.{png,jpg,jpeg}', route => route.abort());\n\n// To disable mocking for a route call `stopMockingRoute`\n// for previously mocked URL\nI.stopMockingRoute('**/*.{png,jpg,jpeg}');\n")])])]),e("p",[t._v("To master request intercepting "),e("a",{attrs:{href:"https://pptr.dev/next/api/puppeteer.httprequest",target:"_blank",rel:"noopener noreferrer"}},[t._v("use HTTPRequest object"),e("OutboundLink")],1),t._v(" passed into mock request handler.")]),t._v(" "),e("p",[t._v("🐛 "),e("em",[t._v("Bug Fixes")])]),t._v(" "),e("ul",[e("li",[t._v("Fixed double help message "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4278",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4278"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/masiuchi",target:"_blank",rel:"noopener noreferrer"}},[t._v("masiuchi"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("waitNumberOfVisibleElements always failed when passing num as 0. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4274",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4274"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-5-15"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-15"}},[t._v("#")]),t._v(" 3.5.15")]),t._v(" "),e("p",[t._v("❤️ Thanks all to those who contributed to make this release! ❤️")]),t._v(" "),e("p",[t._v("🛩️ "),e("em",[t._v("Features")])]),t._v(" "),e("ul",[e("li",[t._v("feat: improve code coverage plugin ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4252",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4252"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)]),t._v("\nWe revamp the coverage plugin to make it easier to use")])]),t._v(" "),e("p",[t._v("Once all the tests are completed, "),e("code",[t._v("codecept")]),t._v(" will create and store coverage in "),e("code",[t._v("output/coverage")]),t._v(" folder, as shown below.")]),t._v(" "),e("p",[e("img",{attrs:{src:"(https://github.com/codeceptjs/CodeceptJS/assets/7845001/3b8b81a3-7c85-470c-992d-ecdc7d5b4a1e)",alt:""}})]),t._v(" "),e("p",[t._v("Open "),e("code",[t._v("index.html")]),t._v(" in your browser to view the full interactive coverage report.")]),t._v(" "),e("p",[e("img",{attrs:{src:"https://github.com/codeceptjs/CodeceptJS/assets/7845001/f45607ed-dbe8-4ed4-9b21-01ce25288d22",alt:""}})]),t._v(" "),e("p",[e("img",{attrs:{src:"https://github.com/codeceptjs/CodeceptJS/assets/7845001/c821ce45-6590-4ace-b7ae-2cafb3a4e532",alt:""}})]),t._v(" "),e("p",[t._v("🐛 "),e("em",[t._v("Bug Fixes")])]),t._v(" "),e("ul",[e("li",[t._v("fix: bump puppeteer to v22.x ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4249",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4249"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: improve dry-run command ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4225",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4225"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("dry-run command now supports test level grep.")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("Tests from /Users/t/Desktop/projects/codeceptjs-rest-demo:@jaja\n\nGET tests -- /Users/t/Desktop/projects/codeceptjs-rest-demo/src/GET_test.ts -- 4 tests\n ☐ Verify getting a single user **[jaja](https://github.com/jaja)**\n ☐ Verify getting list of users **[jaja](https://github.com/jaja)**\nPUT tests -- /Users/t/Desktop/projects/codeceptjs-rest-demo/src/PUT_test.ts -- 4 tests\n ☐ Verify creating new user **[Jaja](https://github.com/Jaja)**\n\n\n Total: 2 suites | 3 tests \n\n--- DRY MODE: No tests were executed ---\n➜ codeceptjs-rest-demo git:(master) ✗ npx codeceptjs dry-run \nTests from /Users/t/Desktop/projects/codeceptjs-rest-demo:\n\nDELETE tests -- /Users/t/Desktop/projects/codeceptjs-rest-demo/src/DELETE_test.ts -- 4 tests\n ☐ Verify deleting a user\nGET tests -- /Users/t/Desktop/projects/codeceptjs-rest-demo/src/GET_test.ts -- 4 tests\n ☐ Verify a successful call\n ☐ Verify a not found call\n ☐ Verify getting a single user **[jaja](https://github.com/jaja)**\n ☐ Verify getting list of users **[jaja](https://github.com/jaja)**\nPOST tests -- /Users/tDesktop/projects/codeceptjs-rest-demo/src/POST_test.ts -- 4 tests\n ☐ Verify creating new user\n ☐ Verify uploading a file\nPUT tests -- /Users/tDesktop/projects/codeceptjs-rest-demo/src/PUT_test.ts -- 4 tests\n ☐ Verify creating new user **[Jaja](https://github.com/Jaja)**\n\n\n Total: 4 suites | 8 tests \n\n--- DRY MODE: No tests were executed ---\n")])])]),e("ul",[e("li",[t._v("Several internal fixes and improvements for github workflows")])]),t._v(" "),e("h2",{attrs:{id:"_3-5-14"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-14"}},[t._v("#")]),t._v(" 3.5.14")]),t._v(" "),e("p",[t._v("❤️ Thanks all to those who contributed to make this release! ❤️")]),t._v(" "),e("p",[t._v("🐛 "),e("em",[t._v("Bug Fixes")])]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Hotfix")]),t._v(" Fixed missing "),e("code",[t._v("joi")]),t._v(" package - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-5-13"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-13"}},[t._v("#")]),t._v(" 3.5.13")]),t._v(" "),e("p",[t._v("❤️ Thanks all to those who contributed to make this release! ❤️")]),t._v(" "),e("p",[t._v("🛩️ "),e("em",[t._v("Features")])]),t._v(" "),e("ul",[e("li",[t._v("feat: mock server helper ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4155",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4155"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)]),t._v(" "),e("img",{attrs:{src:"https://github.com/codeceptjs/CodeceptJS/assets/7845001/8fe7aacf-f1c9-4d7e-89a6-3748b3ccb26c",alt:"Screenshot 2024-01-25 at 13 47 59"}})]),t._v(" "),e("li",[t._v("feat(webdriver): network traffics manipulation ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4166",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4166"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)]),t._v(" "),e("strong",[t._v("[Webdriver]")]),t._v(" Added commands to check network traffics - supported only with devtoolsProtocol\n"),e("ul",[e("li",[e("code",[t._v("startRecordingTraffic")])]),t._v(" "),e("li",[e("code",[t._v("grabRecordedNetworkTraffics")])]),t._v(" "),e("li",[e("code",[t._v("flushNetworkTraffics")])]),t._v(" "),e("li",[e("code",[t._v("stopRecordingTraffic")])]),t._v(" "),e("li",[e("code",[t._v("seeTraffic")])]),t._v(" "),e("li",[e("code",[t._v("dontSeeTraffic")])])])])]),t._v(" "),e("p",[t._v("Examples:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// recording traffics and verify the traffic")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("startRecordingTraffic")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://codecept.io/'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeTraffic")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'traffics'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://codecept.io/img/companies/BC_LogoScreen_C.jpg'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// check the traffic with advanced params")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://openai.com/blog/chatgpt'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("startRecordingTraffic")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeTraffic")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'sentry event'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://images.openai.com/blob/cf717bdb-0c8c-428a-b82b-3c3add87a600'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("parameters")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1919'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1138'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[t._v("feat(webapi): add waitForCookie ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4169",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4169"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)]),t._v("\nWaits for the specified cookie in the cookies.")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForCookie")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"token"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("🐛 "),e("em",[t._v("Bug Fixes")])]),t._v(" "),e("ul",[e("li",[t._v("fix(appium): update performSwipe with w3c protocol v2 ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4181",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4181"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/MykaLev",target:"_blank",rel:"noopener noreferrer"}},[t._v("MykaLev"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(webapi): selectOption method ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4157",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4157"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/dyaroman",target:"_blank",rel:"noopener noreferrer"}},[t._v("dyaroman"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: waitForText doesnt throw error when text doesnt exist ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4195",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4195"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: use this.options instead of this.config ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4186",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4186"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: config path without selenium ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4184",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4184"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: bring to front condition in _setPage ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4173",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4173"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: complicated locator ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4170",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4170"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)]),t._v("\nAdding of "),e("code",[t._v("':nth-child'")]),t._v(" into the array")])]),t._v(" "),e("p",[e("code",[t._v("const limitation = [':nth-of-type', ':first-of-type', ':last-of-type', ':nth-last-child', ':nth-last-of-type', ':checked', ':disabled', ':enabled', ':required', ':lang'];")]),t._v(" fixes the issue. Then an old conversion way over "),e("code",[t._v("css-to-xpath")]),t._v(" is used.")]),t._v(" "),e("p",[t._v("📖 "),e("em",[t._v("Documentation")])]),t._v(" "),e("ul",[e("li",[t._v("fix(docs): missing docs for codecept UI ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4175",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4175"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(docs): Appium documentation sidebar menu links ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4188",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4188"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("🛩️ "),e("strong",[t._v("Several bugfixes and improvements for Codecept-UI")])]),t._v(" "),e("ul",[e("li",[t._v("Several internal improvements")]),t._v(" "),e("li",[t._v("fix: title is not showing when visiting a test")]),t._v(" "),e("li",[t._v("fix: handle erros nicely")])]),t._v(" "),e("h2",{attrs:{id:"_3-5-12"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-12"}},[t._v("#")]),t._v(" 3.5.12")]),t._v(" "),e("p",[t._v("❤️ Thanks all to those who contributed to make this release! ❤️")]),t._v(" "),e("p",[t._v("🛩️ "),e("em",[t._v("Features")])]),t._v(" "),e("ul",[e("li",[e("p",[t._v("feat: upgrade wdio ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4123",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4123"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("p",[t._v("🛩️ With the release of WebdriverIO version "),e("code",[t._v("v8.14.0")]),t._v(", and onwards, all driver management hassles are now a thing of the past 🙌. Read more "),e("a",{attrs:{href:"https://webdriver.io/blog/2023/07/31/driver-management/",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),e("OutboundLink")],1),t._v(".\nOne of the significant advantages of this update is that you can now get rid of any driver services you previously had to manage, such as\n"),e("code",[t._v("wdio-chromedriver-service")]),t._v(", "),e("code",[t._v("wdio-geckodriver-service")]),t._v(", "),e("code",[t._v("wdio-edgedriver-service")]),t._v(", "),e("code",[t._v("wdio-safaridriver-service")]),t._v(", and even "),e("code",[t._v("@wdio/selenium-standalone-service")]),t._v(".")])])]),t._v(" "),e("p",[t._v("For those who require custom driver options, fear not; WebDriver Helper allows you to pass in driver options through custom WebDriver configuration.\nIf you have a custom grid, use a cloud service, or prefer to run your own driver, there's no need to worry since WebDriver Helper will only start a driver when there are no other connection information settings like hostname or port specified.")]),t._v(" "),e("p",[t._v("Example:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("smartWait")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("5000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"chrome"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("restart")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("windowSize")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"maximize"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("timeouts")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"script"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("60000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"page load"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10000")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("Testing Chrome locally is now more convenient than ever. You can define a browser channel, and WebDriver Helper will take care of downloading the specified browser version for you.\nFor example:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("smartWait")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("5000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"chrome"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browserVersion")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'116.0.5793.0'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// or 'stable', 'beta', 'dev' or 'canary'")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("restart")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("windowSize")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"maximize"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("timeouts")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"script"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("60000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"page load"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10000")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("ul",[e("li",[t._v("feat: wdio with devtools protocol ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4105",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4105"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("Running with devtools protocol")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://localhost"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"chrome"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("devtoolsProtocol")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("desiredCapabilities")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("chromeOptions")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("args")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"--headless"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"--disable-gpu"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"--no-sandbox"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("ul",[e("li",[t._v("feat: add a locator builder method withTextEquals() ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4100",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4100"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("Find an element with exact text")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token function"}},[t._v("locate")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'button'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("withTextEquals")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Add'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[t._v("feat: waitForNumberOfTabs ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4124",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4124"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("Waits for number of tabs.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForNumberOfTabs")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[t._v("feat: I.say would be added to Test.steps array ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4145",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4145"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("Currently "),e("code",[t._v("I.say")]),t._v(" is not added into the "),e("code",[t._v("Test.steps")]),t._v(" array. This PR aims to add this to steps array so that we could use it to print steps in ReportPortal for instance.")]),t._v(" "),e("p",[e("img",{attrs:{src:"https://github.com/codeceptjs/CodeceptJS/assets/7845001/82af552a-aeb3-487e-ac10-b5bb7e42470f",alt:"Screenshot 2024-01-19 at 15 41 34"}})]),t._v(" "),e("p",[t._v("🐛 "),e("em",[t._v("Bug Fixes")])]),t._v(" "),e("ul",[e("li",[t._v("fix: reduce the package size to 2MB ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4138",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4138"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(webapi): see attributes on elements ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4147",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4147"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: some assertion methods ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4144",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4144"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("Improve the error message for "),e("code",[t._v("seeElement")]),t._v(", "),e("code",[t._v("dontSeeElement")]),t._v(", "),e("code",[t._v("seeElementInDOM")]),t._v(", "),e("code",[t._v("dontSeeElementInDOM")])]),t._v(" "),e("p",[t._v("The current error message doesn't really help when debugging issue also causes some problem described in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4140",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4140"),e("OutboundLink")],1)]),t._v(" "),e("p",[t._v("Actual")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v(" expected visible elements '[ELEMENT]' to be empty\n + expected - actual\n\n -[\n - \"ELEMENT\"\n -]\n +[]\n")])])]),e("p",[t._v("Updated")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v(' Error: Element "h1" is still visible\n at seeElementError (lib/helper/errors/ElementAssertion.js:9:9)\n at Playwright.dontSeeElement (lib/helper/Playwright.js:1472:7)\n')])])]),e("ul",[e("li",[t._v("fix: css to xpath backward compatibility ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4141",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4141"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://www.npmjs.com/package/css-to-xpath",target:"_blank",rel:"noopener noreferrer"}},[t._v("css-to-xpath"),e("OutboundLink")],1),t._v(": old lib, which works perfectly unless you have hyphen in locator. (https://github.com/codeceptjs/CodeceptJS/issues/3563)")]),t._v(" "),e("li",[e("a",{attrs:{href:"https://www.npmjs.com/package/csstoxpath",target:"_blank",rel:"noopener noreferrer"}},[t._v("csstoxpath"),e("OutboundLink")],1),t._v(": new lib, to solve the issue locator with hyphen but also have some "),e("a",{attrs:{href:"https://www.npmjs.com/package/csstoxpath#limitations",target:"_blank",rel:"noopener noreferrer"}},[t._v("limitations"),e("OutboundLink")],1)])]),t._v(" "),e("ul",[e("li",[t._v("fix: grabRecordedNetworkTraffics throws error when being called twice ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4143",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4143"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: missing steps of test when running with workers ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4127",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4127"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Verify getting list of users'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" res "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("getUserPerPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\nres"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// this line causes the issue")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("expectEqual")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("res"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("at this time, res.data.data[0].id would throw undefined error and somehow the test is missing all its steps.")]),t._v(" "),e("ul",[e("li",[t._v("fix: process.env.profile when --profile isn't set in run-multiple mode ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4131",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4131"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[e("code",[t._v("process.env.profile")]),t._v(' is the string "undefined" instead of type undefined when no --profile is specified in the mode "run-multiple"')]),t._v(" "),e("ul",[e("li",[t._v("fix: session doesn't respect the context options ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4111",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4111"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" Playwright\n"),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Plugins")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" screenshotOnFail"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" tryTo"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" retryFailedStep"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" retryTo"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" eachElement\n\nRepro "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("--")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("**")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("**")]),t._v(" Starting recording promises\n"),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Timeouts")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("\n› "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("**")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Session"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("**")]),t._v(" Starting singleton browser session\nReproduce issue\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" am on page "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"https://example.com"')]),t._v("\n› "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("Browser"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v("Error"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" Failed to load resource"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" the server responded "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("with")]),t._v(" a status "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("of")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("404")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n› "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("New Context"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user1")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" am on page "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"https://example.com"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user1")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" execute "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("script")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" window"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("screen"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("width"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" window"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("screen"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("height "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\nsessionScreen is "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"width"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("375")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"height"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("667")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n✔ "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("OK")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" 1890ms\n\n\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("OK")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("|")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" passed "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 4s")]),t._v("\n")])])]),e("ul",[e("li",[e("p",[t._v("fix(plugin): retryTo issue ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4117",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4117"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)]),t._v(" "),e("img",{attrs:{src:"https://github.com/codeceptjs/CodeceptJS/assets/7845001/39c97073-e2e9-4c4c-86ee-62540bc95015",alt:"Screenshot 2024-01-08 at 17 36 54"}})])]),t._v(" "),e("li",[e("p",[t._v("fix(types): CustomLocator typing broken for custom strict locators ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4120",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4120"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("li",[e("p",[t._v("fix: wrong output for skipped tests - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("li",[e("p",[t._v("fix: no retry failed step after tryto block ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4103",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4103"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("li",[e("p",[t._v("fix: deprecate some JSON Wire Protocol commands ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4104",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4104"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])])]),t._v(" "),e("p",[t._v("deprecate some JSON Wire Protocol commands: "),e("code",[t._v("grabGeoLocation")]),t._v(", "),e("code",[t._v("setGeoLocation")])]),t._v(" "),e("ul",[e("li",[t._v("fix: cannot locate complicated locator ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4101",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4101"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("Locator issue due to the lib changes")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("The locator locate(\".ps-menu-button\").withText(\"Authoring\").inside(\".ps-submenu-root:nth-child(3)\") is translated to\n3.5.8: //*[contains(concat(' ', normalize-space(./@class), ' '), ' ps-menu-button ')][contains(., 'Authoring')][ancestor::*[(contains(concat(' ', normalize-space(./@class), ' '), ' ps-submenu-root ') and count(preceding-sibling::*) = 2)]] and works well\n3.5.11: //*[contains(@class, \"ps-menu-button\")][contains(., 'Authoring')][ancestor::*[3][contains(@class, \"ps-submenu-root\")]] and doesn't work (no clickable element found). Even if you test it in browser inspector, it doesn't work.\n")])])]),e("h2",{attrs:{id:"_3-5-11"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-11"}},[t._v("#")]),t._v(" 3.5.11")]),t._v(" "),e("p",[t._v("❤️ Thanks all to those who contributed to make this release! ❤️")]),t._v(" "),e("p",[t._v("🛩️ "),e("em",[t._v("Features")])]),t._v(" "),e("ul",[e("li",[t._v("feat: other locators from playwright ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4090",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4090"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[t._v("CodeceptJS - Playwright now supports other locators like\n"),e("ul",[e("li",[t._v("React (https://playwright.dev/docs/other-locators#react-locator),")]),t._v(" "),e("li",[t._v("Vue (https://playwright.dev/docs/other-locators#vue-locator)\n"),e("img",{attrs:{src:"https://github.com/codeceptjs/CodeceptJS/assets/7845001/841e9e54-847b-4326-b95f-f9406955a3ce",alt:"Vue Locators"}}),t._v(" "),e("img",{attrs:{src:"https://github.com/codeceptjs/CodeceptJS/assets/7845001/763e6788-143b-4a00-a249-d9ca5f0b2a09",alt:"Example"}})])])])])])]),t._v(" "),e("p",[t._v("🐛 "),e("em",[t._v("Bug Fixes")])]),t._v(" "),e("ul",[e("li",[t._v("fix: step object is broken when step arg is a function ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4092",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4092"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: step object is broken when step arg contains joi object ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4084",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4084"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(expect helper): custom error message as optional param ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4082",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4082"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(puppeteer): hide deprecation info ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4075",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4075"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: seeattributesonelements throws error when attribute doesn't exist ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4073",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4073"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: typo in agrs ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4077",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4077"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: retryFailedStep is disabled for non tryTo steps ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4069",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4069"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(typings): scrollintoview complains scrollintoviewoptions ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4067",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4067"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("📖 "),e("em",[t._v("Documentation")])]),t._v(" "),e("ul",[e("li",[t._v("fix(docs): some doc blocks are broken ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4076",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4076"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(docs): expect docs ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4058",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4058"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-5-10"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-10"}},[t._v("#")]),t._v(" 3.5.10")]),t._v(" "),e("p",[t._v("❤️ Thanks all to those who contributed to make this release! ❤️")]),t._v(" "),e("p",[t._v("🛩️ "),e("em",[t._v("Features")])]),t._v(" "),e("ul",[e("li",[t._v("feat: expose WebElement ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4043",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4043"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("Now we expose the WebElements that are returned by the WebHelper and you could make the subsequence actions on them.\n\n// Playwright helper would return the Locator\n\nI.amOnPage('/form/focus_blur_elements');\nconst webElements = await I.grabWebElements('#button');\nwebElements[0].click();\n")])])]),e("ul",[e("li",[t._v("feat(playwright): support HAR replaying ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3990",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3990"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("Replaying from HAR\n\n // Replay API requests from HAR.\n // Either use a matching response from the HAR,\n // or abort the request if nothing matches.\n I.replayFromHar('./output/har/something.har', { url: \"*/**/api/v1/fruits\" });\n I.amOnPage('https://demo.playwright.dev/api-mocking');\n I.see('CodeceptJS'); **[Parameters]** harFilePath [string](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String) Path to recorded HAR file\nopts [object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object)? [Options for replaying from HAR](https://playwright.dev/docs/api/class-page#page-route-from-har)\n")])])]),e("ul",[e("li",[t._v("feat(playwright): support HAR recording ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3986",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3986"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("A HAR file is an HTTP Archive file that contains a record of all the network requests that are made when a page is loaded. \nIt contains information about the request and response headers, cookies, content, timings, and more. \nYou can use HAR files to mock network requests in your tests. HAR will be saved to output/har. \nMore info could be found here https://playwright.dev/docs/api/class-browser#browser-new-context-option-record-har.\n\n...\nrecordHar: {\n mode: 'minimal', // possible values: 'minimal'|'full'.\n content: 'embed' // possible values: \"omit\"|\"embed\"|\"attach\".\n}\n...\n")])])]),e("ul",[e("li",[t._v("improvement(playwright): support partial string for option ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4016",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4016"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("await I.amOnPage('/form/select');\nawait I.selectOption('Select your age', '21-');\n")])])]),e("p",[t._v("🐛 "),e("em",[t._v("Bug Fixes")])]),t._v(" "),e("ul",[e("li",[t._v("fix(playwright): proceedSee could not find the element ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4006",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4006"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/hatufacci",target:"_blank",rel:"noopener noreferrer"}},[t._v("hatufacci"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(appium): remove the vendor prefix of 'bstack:options' ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4053",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4053"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/mojtabaalavi",target:"_blank",rel:"noopener noreferrer"}},[t._v("mojtabaalavi"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(workers): event improvements ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3953",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3953"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("Emit the new event: event.workers.result.\n\nCodeceptJS also exposes the env var `process.env.RUNS_WITH_WORKERS` when running tests with run-workers command so that you could handle the events better in your plugins/helpers.\n\nconst { event } = require('codeceptjs');\n\nmodule.exports = function() {\n // this event would trigger the `_publishResultsToTestrail` when running `run-workers` command\n event.dispatcher.on(event.workers.result, async () => {\n await _publishResultsToTestrail();\n });\n \n // this event would not trigger the `_publishResultsToTestrail` multiple times when running `run-workers` command\n event.dispatcher.on(event.all.result, async () => {\n // when running `run` command, this env var is undefined\n if (!process.env.RUNS_WITH_WORKERS) await _publishResultsToTestrail();\n });\n}\n")])])]),e("ul",[e("li",[t._v("fix: ai html updates ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3962",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3962"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/DavertMik",target:"_blank",rel:"noopener noreferrer"}},[t._v("DavertMik"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("replaced minify library with a modern and more secure fork. Fixes html-minifier@4.0.0 Regular Expression Denial of Service vulnerability [#3829](https://github.com/codeceptjs/CodeceptJS/issues/3829)\nAI class is implemented as singleton\nrefactored heal.js plugin to work on edge cases\nadd configuration params on number of fixes performed by ay heal\nimproved recorder class to add more verbose log\nimproved recorder class to ignore some of errors\n")])])]),e("ul",[e("li",[t._v("fix(appium): closeApp supports both Android/iOS ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4046",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4046"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: some security vulnerability of some packages ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4045",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4045"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: seeAttributesOnElements check condition ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4029",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4029"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: waitForText locator issue ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4039",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4039"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('Fixed this error:\n\nlocator.isVisible: Unexpected token "s" while parsing selector ":has-text(\'Were you able to resolve the resident\'s issue?\') >> nth=0"\n at Playwright.waitForText (node_modules\\codeceptjs\\lib\\helper\\Playwright.js:2584:79)\n')])])]),e("ul",[e("li",[t._v("fix: move to sha256 ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4038",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4038"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: respect retries from retryfailedstep plugin in helpers ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4028",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4028"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("Currently inside the _before() of helpers for example Playwright, the retries is set there, however, when retryFailedStep plugin is enabled, the retries of recorder is still using the value from _before() not the value from retryFailedStep plugin.\n\nFix:\n\n- introduce the process.env.FAILED_STEP_RETIRES which could be access everywhere as the helper won't know anything about the plugin.\n- set default retries of Playwright to 3 to be on the same page with Puppeteer.\n")])])]),e("ul",[e("li",[t._v("fix: examples in test title ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4030",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4030"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('When test title doesn\'t have the data in examples:\n\nFeature: Faker examples\n\n Scenario Outline: Below are the users\n Examples:\n | user | role |\n | John | admin |\n | Tim | client |\n\nFaker examples --\n **[1]** Starting recording promises\n Timeouts: \n Below are the users {"user":"John","role":"admin"}\n ✔ OK in 4ms\n\n Below are the users {"user":"Tim","role":"client"}\n ✔ OK in 1ms\n\nWhen test title includes the data in examples:\n\n\nFeature: Faker examples\n\n Scenario Outline: Below are the users - - \n Examples:\n | user | role |\n | John | admin |\n | Tim | client |\n\n\nFaker examples --\n **[1]** Starting recording promises\n Timeouts: \n Below are the users - John - admin \n ✔ OK in 4ms\n\n Below are the users - Tim - client \n ✔ OK in 1ms\n')])])]),e("ul",[e("li",[t._v("fix: disable retryFailedStep when using with tryTo ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4022",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4022"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: locator builder returns error when class name contains hyphen ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4024",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4024"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: seeCssPropertiesOnElements failed when font-weight is a number ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4026",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4026"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(appium): missing await on some steps of runOnIOS and runOnAndroid ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4018",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4018"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(cli): no error of failed tests when using retry with scenario only ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4020",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4020"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: set getPageTimeout to 30s ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4031",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4031"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(appium): expose switchToContext ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4015",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4015"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: promise issue ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4013",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4013"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: seeCssPropertiesOnElements issue with improper condition ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4057",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4057"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("📖 "),e("em",[t._v("Documentation")])]),t._v(" "),e("ul",[e("li",[t._v("docs: Update clearCookie documentation for Playwright helper ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4005",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4005"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/Hellosager",target:"_blank",rel:"noopener noreferrer"}},[t._v("Hellosager"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("docs: improve the example code for autoLogin ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/4019",target:"_blank",rel:"noopener noreferrer"}},[t._v("#4019"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)]),t._v(" "),e("img",{attrs:{src:"https://github.com/codeceptjs/CodeceptJS/assets/7845001/c05ac436-efd0-4bc0-a46c-386f915c0f17",alt:"Screenshot 2023-11-22 at 14 40 11"}})])]),t._v(" "),e("h2",{attrs:{id:"_3-5-8"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-8"}},[t._v("#")]),t._v(" 3.5.8")]),t._v(" "),e("p",[t._v("Thanks all to those who contributed to make this release!")]),t._v(" "),e("p",[t._v("🐛 "),e("em",[t._v("Bug Fixes")]),t._v("\nfix(appium): type of setNetworkConnection() ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3994",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3994"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)]),t._v("\nfix: improve the way to show deprecated appium v1 message ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3992",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3992"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)]),t._v("\nfix: missing exit condition of some wait functions - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_3-5-7"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-7"}},[t._v("#")]),t._v(" 3.5.7")]),t._v(" "),e("p",[t._v("Thanks all to those who contributed to make this release!")]),t._v(" "),e("p",[t._v("🐛 "),e("em",[t._v("Bug Fixes")])]),t._v(" "),e("ul",[e("li",[t._v("Bump playwright to 1.39.0 - run "),e("code",[t._v("npx playwright install")]),t._v(" to install the browsers as starting from 1.39.0 browsers are not installed automatically ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3924",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3924"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(playwright): some wait functions draw error due to switchTo iframe ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3918",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3918"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(appium): AppiumTestDistribution/appium-device-farm requires 'platformName' ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3950",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3950"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/rock-tran",target:"_blank",rel:"noopener noreferrer"}},[t._v("rock-tran"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: autologin with empty fetch ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3947",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3947"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/andonary",target:"_blank",rel:"noopener noreferrer"}},[t._v("andonary"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(cli): customLocator draws error in dry-mode ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3940",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3940"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: ensure docs include "),e("strong",[e("a",{attrs:{href:"https://github.com/returns",target:"_blank",rel:"noopener noreferrer"}},[t._v("returns"),e("OutboundLink")],1)]),t._v(" Promise"),e("void",[t._v(" where appropriate ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3954",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3954"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/fwouts",target:"_blank",rel:"noopener noreferrer"}},[t._v("fwouts"),e("OutboundLink")],1)])])],1),t._v(" "),e("li",[t._v("fix: long text in data table cuts off ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3936",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3936"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('#language: de\nFunktionalität: Faker examples\n\n Szenariogrundriss: Atualizar senha do usuário\n Angenommen que estou logado via REST com o usuário ""\n | protocol | https: |\n | hostname | https://cucumber.io/docs/gherkin/languages/ |\n \n\nFaker examples --\n Atualizar senha do usuário {"product":"{{vehicle.vehicle}}","customer":"Dr. {{name.findName}}","price":"{{commerce.price}}","cashier":"cashier 2"}\n On Angenommen: que estou logado via rest com o usuário "dr. {{name.find name}}" \n protocol | https: \n hostname | https://cucumber.io/docs/gherkin/languages/\n \nDr. {{name.findName}}\n ✔ OK in 13ms\n\n')])])]),e("ul",[e("li",[t._v("fix(playwright): move to waitFor ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3933",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3933"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: relax grabCookie type ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3919",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3919"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: proceedSee error when being called inside within ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3939",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3939"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: rename haveRequestHeaders of ppt and pw helpers ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3937",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3937"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("Renamed haveRequestHeaders of Puppeteer, Playwright helper so that it would not confuse the REST helper.\nPuppeteer: setPuppeteerRequestHeaders\nPlaywright: setPlaywrightRequestHeaders\n")])])]),e("ul",[e("li",[t._v("improvement: handle the way to load apifactory nicely ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3941",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3941"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("With this fix, we could now use the following syntax:\n\nexport = new Factory()\n .attr('name', () => faker.name.findName())\n .attr('job', () => 'leader');\n \nexport default new Factory()\n .attr('name', () => faker.name.findName())\n .attr('job', () => 'leader');\n \nmodules.export = new Factory()\n .attr('name', () => faker.name.findName())\n .attr('job', () => 'leader');\n")])])]),e("p",[t._v("📖 "),e("em",[t._v("Documentation")])]),t._v(" "),e("ul",[e("li",[t._v("docs(appium): update to v2 ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3932",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3932"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("docs: improve BDD Gherkin docs ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3938",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3938"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Other docs improvements")])]),t._v(" "),e("p",[t._v("🛩️ "),e("em",[t._v("Features")])]),t._v(" "),e("ul",[e("li",[t._v("feat(puppeteer): support trace recording - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("[Trace Recording Customization]\nTrace recording provides complete information on test execution and includes screenshots, and network requests logged during run. Traces will be saved to output/trace\n\ntrace: enables trace recording for failed tests; trace are saved into output/trace folder\nkeepTraceForPassedTests: - save trace for passed tests\n")])])]),e("ul",[e("li",[t._v("feat: expect helper ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3923",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3923"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v(" * This helper allows performing assertions based on Chai.\n *\n * ### Examples\n *\n * Zero-configuration when paired with other helpers like REST, Playwright:\n *\n * ```js\n * // inside codecept.conf.js\n *{\n * helpers: {\n * Playwright: {...},\n * ExpectHelper: {},\n * }\n \n Expect Helper\n #expectEqual\n #expectNotEqual\n #expectContain\n #expectNotContain\n #expectStartsWith\n #expectNotStartsWith\n #expectEndsWith\n #expectNotEndsWith\n #expectJsonSchema\n #expectHasProperty\n #expectHasAProperty\n #expectToBeA\n #expectToBeAn\n #expectMatchRegex\n #expectLengthOf\n #expectTrue\n #expectEmpty\n #expectFalse\n #expectAbove\n #expectBelow\n #expectLengthAboveThan\n #expectLengthBelowThan\n #expectLengthBelowThan\n #expectDeepMembers\n #expectDeepIncludeMembers\n #expectDeepEqualExcluding\n #expectLengthBelowThan\n")])])]),e("ul",[e("li",[t._v("feat: run-workers with multiple browsers output folders - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("ul",[e("li",[e("img",{attrs:{src:"https://github.com/codeceptjs/CodeceptJS/assets/7845001/8eaecc54-de14-4597-b148-1e087bec3c76",alt:"Screenshot 2023-11-04 at 10 49 56"}})]),t._v(" "),e("li",[e("img",{attrs:{src:"https://github.com/codeceptjs/CodeceptJS/assets/7845001/715aed17-3535-48df-80dd-84f7024f08e3",alt:"Screenshot 2023-11-03 at 15 56 38"}})])]),t._v(" "),e("ul",[e("li",[t._v("feat: introduce new Playwright methods - by "),e("strong",[e("a",{attrs:{href:"https://github.com/hatufacci",target:"_blank",rel:"noopener noreferrer"}},[t._v("hatufacci"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("- grabCheckedElementStatus\n- grabDisabledElementStatus\n")])])]),e("ul",[e("li",[t._v("feat: gherkin supports i18n ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3934",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3934"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('#language: de\nFunktionalität: Checkout-Prozess\n Um Produkte zu kaufen\n Als Kunde\n Möchte ich in der Lage sein, mehrere Produkte zu kaufen\n\n **[i18n](https://github.com/i18n)**\n Szenariogrundriss: Bestellrabatt\n Angenommen ich habe ein Produkt mit einem Preis von $ in meinem Warenkorb\n Und der Rabatt für Bestellungen über $20 beträgt 10 %\n Wenn ich zur Kasse gehe\n Dann sollte ich den Gesamtpreis von "" $ sehen\n\n Beispiele:\n | price | total |\n | 10 | 10.0 |\n')])])]),e("ul",[e("li",[t._v("feat(autoLogin): improve the check method ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3935",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3935"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("Instead of asserting on page elements for the current user in check, you can use the session you saved in fetch\n\nautoLogin: {\n enabled: true,\n saveToFile: true,\n inject: 'login',\n users: {\n admin: {\n login: async (I) => { // If you use async function in the autoLogin plugin\n const phrase = await I.grabTextFrom('#phrase')\n I.fillField('username', 'admin'),\n I.fillField('password', 'password')\n I.fillField('phrase', phrase)\n },\n check: (I, session) => {\n // Throwing an error in `check` will make CodeceptJS perform the login step for the user\n if (session.profile.email !== the.email.you.expect@some-mail.com) {\n throw new Error ('Wrong user signed in');\n }\n },\n }\n }\n}\nScenario('login', async ( {I, login} ) => {\n await login('admin') // you should use `await`\n})\n")])])]),e("h2",{attrs:{id:"_3-5-6"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-6"}},[t._v("#")]),t._v(" 3.5.6")]),t._v(" "),e("p",[t._v("Thanks all to those who contributed to make this release!")]),t._v(" "),e("p",[t._v("🐛 "),e("em",[t._v("Bug Fixes")])]),t._v(" "),e("ul",[e("li",[t._v("fix: switchTo/within block doesn't switch to expected iframe ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3892",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3892"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: highlight element doesn't work as expected ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3896",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3896"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v(" verbose/ highlight\tTRUE\tTRUE -> highlight element\n verbose/ highlight\tTRUE\tFALSE -> no highlight element\n verbose/ highlight\tFALSE\tTRUE -> no highlight element\n verbose/ highlight\tFALSE\tFALSE -> no highlight element\n")])])]),e("ul",[e("li",[t._v("fix: masked value issue in data table ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3885",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3885"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("const accounts = new DataTable(['role', 'username', 'password']);\naccounts.add([\n 'ROLE_A',\n process.env['FIRST_USERNAME'],\n secret(process.env['FIRST_PASSWORD']),\n]);\naccounts.add([\n 'ROLE_B',\n process.env['SECOND_USERNAME'],\n secret(process.env['SECOND_PASSWORD']),\n]);\n\nData(accounts)\n .Scenario(\n 'ScenarioTitle',\n ({ I, pageObject, current }) => {\n I.say(\"Given I'am logged in\");\n I.amOnPage('/');\n loginPage.**sendForm**(current.username, current.password);\n )\n \n \n // output\n The test feature --\n The scenario | {\"username\":\"Username\",\"password\": ***}\n 'The real password: theLoggedPasswordInCleartext'\n I.fillField('somePasswordLocator', '****')\n ✔ OK in 7ms\n\n The scenario | {\"username\":\"theSecondUsername\",\"password\": ***}\n 'The real password: theLoggedPasswordInCleartext'\n I.fillField('somePasswordLocator', '****')\n ✔ OK in 1ms\n")])])]),e("ul",[e("li",[t._v("fix: debug info causes error ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3882",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3882"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("📖 "),e("em",[t._v("Documentation")])]),t._v(" "),e("ul",[e("li",[t._v("fix: get rid of complaining when using session without await and returning nothing. ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3899",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3899"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix(FileSystem): a typo in writeToFile() ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3897",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3897"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("🛩️ "),e("em",[t._v("Features")])]),t._v(" "),e("ul",[e("li",[t._v("feat(translation): add more french keywords and fix deprecated waitForClickable ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3906",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3906"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/andonary",target:"_blank",rel:"noopener noreferrer"}},[t._v("andonary"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('- Add some french keywords for translation\n- I.waitForClickable has the same "attends" than I.wait. Using "attends" leads to use the deprecated waitForClickable. Fix it by using different words.\n')])])]),e("h2",{attrs:{id:"_3-5-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-5"}},[t._v("#")]),t._v(" 3.5.5")]),t._v(" "),e("p",[t._v("🐛 Bug Fixes")]),t._v(" "),e("ul",[e("li",[t._v("fix(browserstack): issue with vendor prefix ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3845",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3845"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("export const caps = {\n androidCaps: {\n appiumV2: true,\n host: \"hub-cloud.browserstack.com\",\n port: 4444,\n user: process.env.BROWSERSTACK_USER,\n key: process.env.BROWSERSTACK_KEY,\n 'app': `bs://c700ce60cf13ae8ed97705a55b8e022f1hjhkjh3c5827c`,\n browser: '',\n desiredCapabilities: {\n 'appPackage': data.packageName,\n 'deviceName': process.env.DEVICE || 'Google Pixel 3',\n 'platformName': process.env.PLATFORM || 'android',\n 'platformVersion': process.env.OS_VERSION || '10.0',\n 'automationName': process.env.ENGINE || 'UIAutomator2',\n 'newCommandTimeout': 300000,\n 'androidDeviceReadyTimeout': 300000,\n 'androidInstallTimeout': 90000,\n 'appWaitDuration': 300000,\n 'autoGrantPermissions': true,\n 'gpsEnabled': true,\n 'isHeadless': false,\n 'noReset': false,\n 'noSign': true,\n 'bstack:options' : {\n \"appiumVersion\" : \"2.0.1\",\n },\n }\n },\n}\n")])])]),e("ul",[e("li",[t._v("switchTo/within now supports strict locator ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3847",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3847"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("I.switchTo({ css: 'iframe[id^=number-frame]' }) // support the strict locator\n\nI.amOnPage('/iframe');\nwithin({\n frame: { css: '#number-frame-1234' }, // support the strict locator\n}, () => {\n I.fillField('user[login]', 'User');\n I.fillField('user[email]', 'user@user.com');\n I.fillField('user[password]', 'user@user.com');\n I.click('button');\n});\n")])])]),e("ul",[e("li",[t._v("Improve the IntelliSense when using other languages ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3848",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3848"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/andonary",target:"_blank",rel:"noopener noreferrer"}},[t._v("andonary"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v(" include: {\n Je: './steps_file.js'\n }\n")])])]),e("ul",[e("li",[t._v("bypassCSP support for Playwright helper ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3865",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3865"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/sammeel",target:"_blank",rel:"noopener noreferrer"}},[t._v("sammeel"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v(" helpers: {\n Playwright: {\n bypassCSP: true\n }\n")])])]),e("ul",[e("li",[t._v("fix: missing requests when recording network ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3834",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3834"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("🛩️ Features and Improvements")]),t._v(" "),e("ul",[e("li",[t._v("Show environment info in verbose mode ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3858",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3858"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('Environment information:-\n\ncodeceptVersion: "3.5.4"\nnodeInfo: 18.16.0\nosInfo: macOS 13.5\ncpuInfo: (8) arm64 Apple M1 Pro\nchromeInfo: 116.0.5845.179\nedgeInfo: 116.0.1938.69\nfirefoxInfo: Not Found\nsafariInfo: 16.6\nhelpers: {\n"Playwright": {\n"url": "https://github.com",\n"show": false,\n"browser": "chromium",\n"waitForNavigation": "load",\n"waitForTimeout": 30000,\n"trace": false,\n"keepTraceForPassedTests": true\n},\n"CDPHelper": {\n"require": "./helpers/CDPHelper.ts"\n},\n"OpenAI": {\n"chunkSize": 8000\n},\n"ExpectHelper": {\n"require": "codeceptjs-expect"\n},\n"REST": {\n"endpoint": "https://reqres.in",\n"timeout": 20000\n},\n"AllureHelper": {\n"require": "./helpers/AllureHelper.ts"\n}\n}\nplugins: {\n"screenshotOnFail": {\n"enabled": true\n},\n"tryTo": {\n"enabled": true\n},\n"retryFailedStep": {\n"enabled": true\n},\n"retryTo": {\n"enabled": true\n},\n"eachElement": {\n"enabled": true\n},\n"pauseOnFail": {}\n}\n***************************************\nIf you have questions ask them in our Slack: http://bit.ly/chat-codeceptjs\nOr ask them on our discussion board: https://codecept.discourse.group/\nPlease copy environment info when you report issues on GitHub: https://github.com/Codeception/CodeceptJS/issues\n***************************************\nCodeceptJS v3.5.4 #StandWithUkraine\n')])])]),e("ul",[e("li",[t._v("some typings improvements ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3855",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3855"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/nikzupancic",target:"_blank",rel:"noopener noreferrer"}},[t._v("nikzupancic"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("support the puppeteer 21.1.1 ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3856",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3856"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fix: support secret value for some methods ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3837",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3837"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("await I.amOnPage('/form/field_values');\nawait I.dontSeeInField('checkbox[]', secret('not seen one'));\nawait I.seeInField('checkbox[]', secret('see test one'));\nawait I.dontSeeInField('checkbox[]', secret('not seen two'));\nawait I.seeInField('checkbox[]', secret('see test two'));\nawait I.dontSeeInField('checkbox[]', secret('not seen three'));\nawait I.seeInField('checkbox[]', secret('see test three'));\n")])])]),e("p",[t._v("🛩️ "),e("strong",[t._v("Several bugfixes and improvements for Codecept-UI")])]),t._v(" "),e("ul",[e("li",[t._v("Mask the secret value in UI")]),t._v(" "),e("li",[t._v("Improve UX/UI")]),t._v(" "),e("li",[t._v("PageObjects are now showing in UI")])]),t._v(" "),e("h2",{attrs:{id:"_3-5-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-4"}},[t._v("#")]),t._v(" 3.5.4")]),t._v(" "),e("p",[t._v("🐛 Bug Fixes:")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Playwright]")]),t._v(" When passing "),e("code",[t._v("userDataDir")]),t._v(", it throws error after test execution ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3814",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3814"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[CodeceptJS-CLI] Improve command to generate types ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3788",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3788"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Heal plugin fix ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3820",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3820"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/davert",target:"_blank",rel:"noopener noreferrer"}},[t._v("davert"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fix for error in using "),e("code",[t._v("all")]),t._v(" with "),e("code",[t._v("run-workers")]),t._v(" ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3805",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3805"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Playwright")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://github.com'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("show")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'chromium'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("waitForNavigation")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'load'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("waitForTimeout")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("30_000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("trace")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("keepTraceForPassedTests")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("multiple")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("profile1")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browsers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"chromium"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Highlight elements issues ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3779",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3779"),e("OutboundLink")],1),t._v(") ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3778",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3778"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/philkas",target:"_blank",rel:"noopener noreferrer"}},[t._v("philkas"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Support "),e("code",[t._v(" ")]),t._v(" symbol in "),e("code",[t._v("I.see")]),t._v(" method ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3815",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3815"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// HTML code uses   instead of space")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("div "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"dJHe_"')]),t._v(" style"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"color: rgb(255, 255, 255);"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("My"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("&")]),t._v("nbsp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("Text"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("/")]),t._v("div"),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"My Text!"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// this test would work with both   and space")]),t._v("\n")])])]),e("p",[t._v("📖 Documentation")]),t._v(" "),e("ul",[e("li",[t._v("Improve the configuration of electron testing when the app is build with electron-forge ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3802",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3802"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" path "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"path"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nexports"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Playwright")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"electron"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("electron")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("executablePath")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"electron"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("args")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("path"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("join")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("__dirname"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".webpack/main/index.js"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// rest of config")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("🛩️ Features")]),t._v(" "),e("h4",{attrs:{id:"playwright-new-features-and-improvements"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#playwright-new-features-and-improvements"}},[t._v("#")]),t._v(" "),e("strong",[t._v("[Playwright]")]),t._v(" new features and improvements")]),t._v(" "),e("ul",[e("li",[t._v("Parse the response in recording network steps ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3771",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3771"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" traffics "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabRecordedNetworkTraffics")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("traffics"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("url"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("to"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://reqres.in/api/comments/1'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("traffics"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("response"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("status"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("to"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("traffics"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("response"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("body"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("to"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("contain")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'this was mocked'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("traffics"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("url"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("to"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://reqres.in/api/comments/1'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("traffics"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("response"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("status"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("to"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("traffics"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("response"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("body"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("to"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("contain")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'this was another mocked'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Grab metrics ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3809",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3809"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" metrics "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabMetrics")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// returned metrics")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Timestamp'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1584904.203473")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'AudioHandlers'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'AudioWorkletProcessors'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Documents'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("22")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Frames'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'JSEventListeners'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("366")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'LayoutObjects'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1240")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'MediaKeySessions'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'MediaKeys'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Nodes'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("4505")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Resources'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("141")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'ContextLifecycleStateObservers'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("34")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'V8PerContextDatas'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'WorkerGlobalScopes'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'UACSSResources'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'RTCPeerConnections'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'ResourceFetchers'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("22")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'AdSubframes'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'DetachedScriptStates'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'ArrayBufferContents'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'LayoutCount'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'RecalcStyleCount'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'LayoutDuration'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'RecalcStyleDuration'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'DevToolsCommandDuration'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.000013")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'ScriptDuration'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'V8CompileDuration'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'TaskDuration'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.000014")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'TaskOtherDuration'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.000001")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'ThreadTime'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.000046")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'ProcessTime'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0.616852")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'JSHeapUsedSize'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("19004908")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'JSHeapTotalSize'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("26820608")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'FirstMeaningfulPaint'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'DomContentLoaded'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1584903.690491")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'NavigationStart'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("value")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1584902.841845")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Grab WebSocket (WS) messages ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3789",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3789"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[e("code",[t._v("flushWebSocketMessages")])]),t._v(" "),e("li",[e("code",[t._v("grabWebSocketMessages")])]),t._v(" "),e("li",[e("code",[t._v("startRecordingWebSocketMessages")])]),t._v(" "),e("li",[e("code",[t._v("stopRecordingWebSocketMessages")])])])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("startRecordingWebSocketMessages")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://websocketstest.com/'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForText")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Work for You!'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("flushNetworkTraffics")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" wsMessages "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabWebSocketMessages")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wsMessages"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("to"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("startRecordingWebSocketMessages")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://websocketstest.com/'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForText")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Work for You!'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" wsMessages "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabWebSocketMessages")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wsMessages"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("to"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("greaterThan")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("startRecordingWebSocketMessages")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://websocketstest.com/'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForText")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Work for You!'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" wsMessages "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabWebSocketMessages")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("stopRecordingWebSocketMessages")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://websocketstest.com/'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForText")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Work for You!'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" afterWsMessages "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabWebSocketMessages")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("wsMessages"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("to"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("afterWsMessages"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("length"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Move from "),e("code",[t._v("ElementHandle")]),t._v(" to "),e("code",[t._v("Locator")]),t._v(". This change is quite major, but it happened under hood, so should not affect your code. ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3738",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3738"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-5-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-3"}},[t._v("#")]),t._v(" 3.5.3")]),t._v(" "),e("p",[t._v("🛩️ Features")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Added commands to check network traffic "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3748",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3748"),e("OutboundLink")],1),t._v(" - by "),e("strong",[e("a",{attrs:{href:"https://github.com/ngraf",target:"_blank",rel:"noopener noreferrer"}},[t._v("ngraf"),e("OutboundLink")],1)]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[e("code",[t._v("startRecordingTraffic")])]),t._v(" "),e("li",[e("code",[t._v("grabRecordedNetworkTraffics")])]),t._v(" "),e("li",[e("code",[t._v("blockTraffic")])]),t._v(" "),e("li",[e("code",[t._v("mockTraffic")])]),t._v(" "),e("li",[e("code",[t._v("flushNetworkTraffics")])]),t._v(" "),e("li",[e("code",[t._v("stopRecordingTraffic")])]),t._v(" "),e("li",[e("code",[t._v("seeTraffic")])]),t._v(" "),e("li",[e("code",[t._v("grabTrafficUrl")])]),t._v(" "),e("li",[e("code",[t._v("dontSeeTraffic")])])])])]),t._v(" "),e("p",[t._v("Examples:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// recording traffics and verify the traffic")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("startRecordingTraffic")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://codecept.io/'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeTraffic")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'traffics'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://codecept.io/img/companies/BC_LogoScreen_C.jpg'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// block the traffic")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("blockTraffic")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://reqres.in/api/comments/*'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/form/fetch_call'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("startRecordingTraffic")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'GET COMMENTS'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Can not load data!'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// check the traffic with advanced params")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://openai.com/blog/chatgpt'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("startRecordingTraffic")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeTraffic")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'sentry event'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://images.openai.com/blob/cf717bdb-0c8c-428a-b82b-3c3add87a600'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("parameters")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("width")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1919'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1138'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("🐛 Bugfix")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[retryStepPlugin]")]),t._v(" Fix retry step when using global retry "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3768",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3768"),e("OutboundLink")],1),t._v(" - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("🗑 Deprecated")]),t._v(" "),e("ul",[e("li",[t._v("Nightmare and Protractor helpers have been deprecated")])]),t._v(" "),e("h2",{attrs:{id:"_3-5-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-2"}},[t._v("#")]),t._v(" 3.5.2")]),t._v(" "),e("p",[t._v("🐛 Bug Fixes")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Playwright]")]),t._v(" reverted "),e("code",[t._v("clearField")]),t._v(" to previous implementation")]),t._v(" "),e("li",[e("strong",[t._v("[OpenAI]")]),t._v(" fixed running helper in pause mode. "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3755",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3755"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-5-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-1"}},[t._v("#")]),t._v(" 3.5.1")]),t._v(" "),e("p",[t._v("🛩️ Features")]),t._v(" "),e("ul",[e("li",[t._v("[Puppeteer][WebDriver][TestCafe] Added methods by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3737",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3737"),e("OutboundLink")],1),t._v(" "),e("ul",[e("li",[e("code",[t._v("blur")])]),t._v(" "),e("li",[e("code",[t._v("focus")])])])]),t._v(" "),e("li",[t._v("Improved BDD output to print steps without "),e("code",[t._v("I.")]),t._v(" commands` by "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)]),t._v(" "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3739",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3739"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Improved "),e("code",[t._v("codecept init")]),t._v(" setup for Electron tests by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3733",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3733"),e("OutboundLink")],1)])]),t._v(" "),e("p",[t._v("🐛 Bug Fixes")]),t._v(" "),e("ul",[e("li",[t._v("Fixed serializing of custom errors making tests stuck. Fix "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3739",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3739"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)]),t._v(".")])]),t._v(" "),e("p",[t._v("📖 Documentation")]),t._v(" "),e("ul",[e("li",[t._v("Fixed Playwright docs by "),e("strong",[e("a",{attrs:{href:"https://github.com/Horsty80",target:"_blank",rel:"noopener noreferrer"}},[t._v("Horsty80"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed ai docs by "),e("strong",[e("a",{attrs:{href:"https://github.com/ngraf",target:"_blank",rel:"noopener noreferrer"}},[t._v("ngraf"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Various fixes by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-5-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-5-0"}},[t._v("#")]),t._v(" 3.5.0")]),t._v(" "),e("p",[t._v("🛩️ Features")]),t._v(" "),e("ul",[e("li",[e("p",[e("strong",[t._v("🪄 "),e("a",{attrs:{href:"/ai"}},[t._v("AI Powered Test Automation")])]),t._v(" - use OpenAI as a copilot for test automation. "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3713",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3713"),e("OutboundLink")],1),t._v(" By "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)]),t._v(" "),e("img",{attrs:{src:"https://user-images.githubusercontent.com/220264/250418764-c382709a-3ccb-4eb5-b6bc-538f3b3b3d35.png",alt:""}})]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"/ai"}},[t._v("AI guide")]),t._v(" added")]),t._v(" "),e("li",[t._v("added support for OpenAI in "),e("code",[t._v("pause()")])]),t._v(" "),e("li",[t._v("added "),e("a",{attrs:{href:"/plugins#heal"}},[e("code",[t._v("heal")]),t._v(" plugin")]),t._v(" for self-healing tests")]),t._v(" "),e("li",[t._v("added "),e("a",{attrs:{href:"/helpers/openai"}},[e("code",[t._v("OpenAI")])]),t._v(" helper")])])]),t._v(" "),e("li",[e("p",[t._v("[Playwright][Puppeteer][WebDriver] Highlight the interacting elements in debug mode or with "),e("code",[t._v("highlightElement")]),t._v(" option set ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3672",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3672"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])])]),t._v(" "),e("p",[e("img",{attrs:{src:"https://user-images.githubusercontent.com/220264/250415226-a7620418-56a4-4837-b790-b15e91e5d1f0.png",alt:""}})]),t._v(" "),e("ul",[e("li",[e("p",[e("strong",[t._v("[Playwright]")]),t._v(" Support for APIs in Playwright ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3665",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3665"),e("OutboundLink")],1),t._v(") - by Egor Bodnar")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("clearField")]),t._v(" replaced to use new Playwright API")]),t._v(" "),e("li",[e("code",[t._v("blur")]),t._v(" added")]),t._v(" "),e("li",[e("code",[t._v("focus")]),t._v(" added")])])]),t._v(" "),e("li",[e("p",[e("strong",[e("a",{attrs:{href:"/parallel#Parallel-Execution-by-Workers-on-Multiple-Browsers"}},[t._v("Added support for multiple browsers")])]),t._v(" in "),e("code",[t._v("run-workers")]),t._v(" ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3606",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3606"),e("OutboundLink")],1),t._v(") by "),e("strong",[e("a",{attrs:{href:"https://github.com/karanshah-browserstack",target:"_blank",rel:"noopener noreferrer"}},[t._v("karanshah-browserstack"),e("OutboundLink")],1)]),t._v(" :")])])]),t._v(" "),e("p",[t._v("Multiple browsers configured as profiles:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[t._v("exports"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'http://localhost:3000'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("multiple")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("profile1")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browsers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"firefox"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"chrome"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n")])])]),e("p",[t._v("And executed via "),e("code",[t._v("run-workers")]),t._v(" with "),e("code",[t._v("all")]),t._v(" argument")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("npx codeceptjs run-workers 2 all\n")])])]),e("ul",[e("li",[e("strong",[t._v("[Appium]")]),t._v(" Add Appium v2 support ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3622",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3622"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Improve "),e("code",[t._v("gpo")]),t._v(" command to create page objects as modules or as classes ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3625",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3625"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("emptyOutputFolder")]),t._v(" config to clean up output before running tests ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3604",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3604"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Add "),e("code",[t._v("secret()")]),t._v(" function support to "),e("code",[t._v("append()")]),t._v(" and "),e("code",[t._v("type()")]),t._v(" ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3615",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3615"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/anils92",target:"_blank",rel:"noopener noreferrer"}},[t._v("anils92"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Add "),e("code",[t._v("bypassCSP")]),t._v(" option to helper's config ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3641",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3641"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Print number of tests for each suite in dryRun ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3620",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3620"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("🐛 Bug Fixes")]),t._v(" "),e("ul",[e("li",[t._v("Support "),e("code",[t._v("--grep")]),t._v(" in dry-run command ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3673",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3673"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fix typings improvements in playwright ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3650",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3650"),e("OutboundLink")],1),t._v(") - by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed global retry "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3667",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3667"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/KobeNguyenT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KobeNguyenT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v('Fixed creating JavaScript test using "codeceptjs gt" ('),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3611",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3611"),e("OutboundLink")],1),t._v(") - by Jaromir Obr")])]),t._v(" "),e("h2",{attrs:{id:"_3-4-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-4-1"}},[t._v("#")]),t._v(" 3.4.1")]),t._v(" "),e("ul",[e("li",[t._v("Updated mocha to v 10.2. Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3591",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3591"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Fixes executing a faling Before hook. Resolves "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3592",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3592"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_3-4-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-4-0"}},[t._v("#")]),t._v(" 3.4.0")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Updated to latest mocha and modern Cucumber")])]),t._v(" "),e("li",[e("strong",[t._v("Allure plugin moved to "),e("a",{attrs:{href:"https://github.com/codeceptjs/allure-legacy",target:"_blank",rel:"noopener noreferrer"}},[t._v("@codeceptjs/allure-legacy"),e("OutboundLink")],1),t._v(" package")]),t._v(". This happened because allure-commons package v1 was not updated and caused vulnarabilities. Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3422",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3422"),e("OutboundLink")],1),t._v(". We don't plan to maintain allure v2 plugin so it's up to community to take this initiative. Current allure plugin will print a warning message without interfering the run, so it won't accidentally fail your builds.")]),t._v(" "),e("li",[t._v("Added ability to "),e("strong",[e("a",{attrs:{href:"https://codecept.io/basics/#retry-before",target:"_blank",rel:"noopener noreferrer"}},[t._v("retry Before"),e("OutboundLink")],1),t._v(", BeforeSuite, After, AfterSuite")]),t._v(" hooks by "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)]),t._v(":")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'flaky Before & BeforeSuite'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("retryBefore")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("retryBeforeSuite")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("ul",[e("li",[e("strong",[t._v("Flexible "),e("a",{attrs:{href:"https://codecept.io/basics/#retry-configuration",target:"_blank",rel:"noopener noreferrer"}},[t._v("retries configuration"),e("OutboundLink")],1),t._v(" introduced")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)]),t._v(":")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("retry")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// enable this config only for flaky tests")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("grep")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@flaky'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Before")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// retry Before 3 times")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Scenario")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// retry Scenario 3 times")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" \n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// retry less when running slow tests")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("grep")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@slow'")]),t._v(" \n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Scenario")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Before")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// retry all BeforeSuite 3 times")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("BeforeSuite")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),e("ul",[e("li",[e("strong",[t._v("Flexible "),e("a",{attrs:{href:"https://codecept.io/advanced/#timeout-configuration",target:"_blank",rel:"noopener noreferrer"}},[t._v("timeout configuration"),e("OutboundLink")],1)]),t._v(" introduced by "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)]),t._v(":")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("timeout")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// default timeout is 10secs ")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// but increase timeout for slow tests")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("grep")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@slow'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Feature")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("50")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),e("ul",[e("li",[t._v("JsDoc: Removed promise from "),e("code",[t._v("I.say")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3535",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3535"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/danielrentz",target:"_blank",rel:"noopener noreferrer"}},[t._v("danielrentz"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" "),e("code",[t._v("handleDownloads")]),t._v(" requires now a filename param. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3511",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3511"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Added support for v8, removed support for webdriverio v5 and lower. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3578",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3578"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-3-7"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-3-7"}},[t._v("#")]),t._v(" 3.3.7")]),t._v(" "),e("p",[t._v("🛩️ Features")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Promise-based typings")]),t._v(" for TypeScript definitions in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3465",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3465"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/nlespiaucq",target:"_blank",rel:"noopener noreferrer"}},[t._v("nlespiaucq"),e("OutboundLink")],1)]),t._v(". If you use TypeScript or use linters "),e("a",{attrs:{href:"https://bit.ly/3XIMq6n",target:"_blank",rel:"noopener noreferrer"}},[t._v("check how it may be useful to you"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("Translation")]),t._v(" improved to use "),e("a",{attrs:{href:"https://codecept.io/translation/",target:"_blank",rel:"noopener noreferrer"}},[t._v("custom vocabulary"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Added methods in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3398",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3398"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[e("code",[t._v("restartBrowser")]),t._v(" - to restart a browser (with different config)")]),t._v(" "),e("li",[e("code",[t._v("_createContextPage")]),t._v(" - to create a new browser context with a page from a helper")])])]),t._v(" "),e("li",[t._v("Added "),e("a",{attrs:{href:"/bdd#custom-types"}},[t._v("Cucumber custom types")]),t._v(" for BDD in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3435",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3435"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Likstern",target:"_blank",rel:"noopener noreferrer"}},[t._v("Likstern"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Propose using JSONResponse helper when initializing project for API testing. "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3455",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3455"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("When translation enabled, generate tests using localized aliases. By "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Appium]")]),t._v(" Added "),e("code",[t._v("checkIfAppIsInstalled")]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3507",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3507"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("🐛 Bugfixes")]),t._v(" "),e("ul",[e("li",[t._v("Fixed "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3462",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3462"),e("OutboundLink")],1),t._v(" "),e("code",[t._v("TypeError: Cannot read properties of undefined (reading 'setStatus')")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/dwentland24",target:"_blank",rel:"noopener noreferrer"}},[t._v("dwentland24"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3438",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3438"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Fixed creating steps file for TypeScript setup "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3459",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3459"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed issue of after all event in "),e("code",[t._v("run-rerun")]),t._v(" command after complete execution "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3464",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3464"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/jain-neeeraj",target:"_blank",rel:"noopener noreferrer"}},[t._v("jain-neeeraj"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[Playwright][WebDriver][Appium] Do not change "),e("code",[t._v("waitForTimeout")]),t._v(" value on validation. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3478",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3478"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/pmajewski24",target:"_blank",rel:"noopener noreferrer"}},[t._v("pmajewski24"),e("OutboundLink")],1)]),t._v(". Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2589",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2589"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("[Playwright][WebDriver][Protractor][Puppeteer][TestCafe] Fixes "),e("code",[t._v('Element "{null: undefined}" was not found')]),t._v(" and "),e("code",[t._v("element ([object Object]) still not present")]),t._v(" messages when using object locators. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3501",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3501"),e("OutboundLink")],1),t._v(" and "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3502",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3502"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/pmajewski24",target:"_blank",rel:"noopener noreferrer"}},[t._v("pmajewski24"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Improved file names when downloading file in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3449",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3449"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(". Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3412",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3412"),e("OutboundLink")],1),t._v(" and "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3409",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3409"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Add default value to "),e("code",[t._v("profile")]),t._v(" env variable. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3443",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3443"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/dwentland24",target:"_blank",rel:"noopener noreferrer"}},[t._v("dwentland24"),e("OutboundLink")],1)]),t._v(". Resolves "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3339",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3339"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Using system-native path separator when saving artifacts in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3460",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3460"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Saving videos and traces from multiple sessions in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3505",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3505"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Fixed "),e("code",[t._v("amOnPage")]),t._v(" to navigate to "),e("code",[t._v("about:blank")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/zaxoavoki",target:"_blank",rel:"noopener noreferrer"}},[t._v("zaxoavoki"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3470",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3470"),e("OutboundLink")],1),t._v(" Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2311",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2311"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Various typing improvements by "),e("strong",[e("a",{attrs:{href:"https://github.com/AWolf81",target:"_blank",rel:"noopener noreferrer"}},[t._v("AWolf81"),e("OutboundLink")],1)]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("📖 Documentation")]),t._v(" "),e("ul",[e("li",[t._v("Updated "),e("a",{attrs:{href:"https://codecept.io/quickstart/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Quickstart"),e("OutboundLink")],1),t._v(" with detailed explanation of questions in init")]),t._v(" "),e("li",[t._v("Added "),e("RouterLink",{attrs:{to:"/translation/"}},[t._v("Translation")]),t._v(" guide")],1),t._v(" "),e("li",[t._v("Updated "),e("a",{attrs:{href:"https://bit.ly/3XIMq6n",target:"_blank",rel:"noopener noreferrer"}},[t._v("TypeScript"),e("OutboundLink")],1),t._v(" guide for promise-based typings")]),t._v(" "),e("li",[t._v("Reordered guides list on a website")])]),t._v(" "),e("h2",{attrs:{id:"_3-3-6"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-3-6"}},[t._v("#")]),t._v(" 3.3.6")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://codecept.io/commands/#run-rerun",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("run-rerun")]),e("OutboundLink")],1),t._v(" command was re-introduced by "),e("strong",[e("a",{attrs:{href:"https://github.com/dwentland24",target:"_blank",rel:"noopener noreferrer"}},[t._v("dwentland24"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3436",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3436"),e("OutboundLink")],1),t._v(". Use it to perform run multiple times and detect flaky tests")]),t._v(" "),e("li",[t._v("Enabled "),e("code",[t._v("retryFailedStep")]),t._v(" by default in "),e("code",[t._v("@codeceptjs/configure")]),t._v(" v 0.10. See https://github.com/codeceptjs/configure/pull/26")]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(' Fixed properties types "waitForNavigation" and "firefox" by '),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3401",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3401"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("strong",[t._v("[REST]")]),t._v(' Changed "endpoint" to optional by '),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3404",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3404"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("strong",[t._v("[REST]")]),t._v(" Use "),e("a",{attrs:{href:"/secrets"}},[e("code",[t._v("secret")])]),t._v(" for form encoded string by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(":")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" secretData "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("secret")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'name=john&password=123456'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendPostRequest")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/user'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" secretData"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[t._v('[Playwright]Fixed docs related to fixed properties types "waitForNavigation" and "firefox" by '),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3407",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3407"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("[Playwright]Fixed parameters of startActivity() by "),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3408",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3408"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Move semver to prod dependencies by "),e("strong",[e("a",{attrs:{href:"https://github.com/timja",target:"_blank",rel:"noopener noreferrer"}},[t._v("timja"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3413",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3413"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("check if browser is W3C instead of Android by "),e("strong",[e("a",{attrs:{href:"https://github.com/mikk150",target:"_blank",rel:"noopener noreferrer"}},[t._v("mikk150"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3414",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3414"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Pass service configs with options and caps as array for browsers… by "),e("strong",[e("a",{attrs:{href:"https://github.com/07souravkunda",target:"_blank",rel:"noopener noreferrer"}},[t._v("07souravkunda"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3418",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3418"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v('fix for type of "webdriver.port" by '),e("strong",[e("a",{attrs:{href:"https://github.com/ngraf",target:"_blank",rel:"noopener noreferrer"}},[t._v("ngraf"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3421",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3421"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v('fix for type of "webdriver.smartWait" by '),e("strong",[e("a",{attrs:{href:"https://github.com/pmajewski24",target:"_blank",rel:"noopener noreferrer"}},[t._v("pmajewski24"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3426",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3426"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("fix(datatable): mask secret text by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3432",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3432"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("fix(playwright) - video name and missing type by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3430",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3430"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v('fix for expected type of "bootstrap", "teardown", "bootstrapAll" and "teardownAll" by '),e("strong",[e("a",{attrs:{href:"https://github.com/ngraf",target:"_blank",rel:"noopener noreferrer"}},[t._v("ngraf"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3424",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3424"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Improve generate pageobject "),e("code",[t._v("gpo")]),t._v(" command to work with TypeScript by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3411",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3411"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Fixed dry-run to always return 0 code and exit")]),t._v(" "),e("li",[t._v("Added minimal version notice for NodeJS >= 12")]),t._v(" "),e("li",[t._v("fix(utils): remove . of test title to avoid confusion by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3431",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3431"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_3-3-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-3-5"}},[t._v("#")]),t._v(" 3.3.5")]),t._v(" "),e("p",[t._v("🛩️ Features")]),t._v(" "),e("ul",[e("li",[t._v("Added "),e("strong",[t._v("TypeScript types for CodeceptJS config")]),t._v(".")])]),t._v(" "),e("p",[t._v("Update "),e("code",[t._v("codecept.conf.js")]),t._v(" to get intellisense when writing config file:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/**@type {CodeceptJS.MainConfig}**/")]),t._v("\nexports"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//...")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Added TS types for helpers config:\n"),e("ul",[e("li",[t._v("Playwright")]),t._v(" "),e("li",[t._v("Puppeteer")]),t._v(" "),e("li",[t._v("WebDriver")]),t._v(" "),e("li",[t._v("REST")])])]),t._v(" "),e("li",[t._v("Added "),e("strong",[e("a",{attrs:{href:"/typescript"}},[t._v("TypeScript option")])]),t._v(" for installation via "),e("code",[t._v("codeceptjs init")]),t._v(" to initialize new projects in TS (by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(" and "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)]),t._v(")")]),t._v(" "),e("li",[t._v("Includes "),e("code",[t._v("node-ts")]),t._v(" automatically when using TypeScript setup.")])]),t._v(" "),e("p",[t._v("🐛 Bugfixes")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed support for Puppeteer > 14.4 by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Don't report files as existing when non-directory is in path by "),e("strong",[e("a",{attrs:{href:"https://github.com/jonathanperret",target:"_blank",rel:"noopener noreferrer"}},[t._v("jonathanperret"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3374",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3374"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Fixed TS type for "),e("code",[t._v("secret")]),t._v(" function by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed wrong order for async MetaSteps by "),e("strong",[e("a",{attrs:{href:"https://github.com/dwentland24",target:"_blank",rel:"noopener noreferrer"}},[t._v("dwentland24"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3393",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3393"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Fixed same param substitution in BDD step. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3385",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3385"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/snehabhandge",target:"_blank",rel:"noopener noreferrer"}},[t._v("snehabhandge"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("📖 Documentation")]),t._v(" "),e("ul",[e("li",[t._v("Updated "),e("a",{attrs:{href:"https://codecept.io/configuration/",target:"_blank",rel:"noopener noreferrer"}},[t._v("configuration options"),e("OutboundLink")],1),t._v(" to match TypeScript types")]),t._v(" "),e("li",[t._v("Updated "),e("a",{attrs:{href:"https://codecept.io/typescript/",target:"_blank",rel:"noopener noreferrer"}},[t._v("TypeScript documentation"),e("OutboundLink")],1),t._v(" on simplifying TS installation")]),t._v(" "),e("li",[t._v("Added codecept-tesults plugin documentation by "),e("strong",[e("a",{attrs:{href:"https://github.com/ajeetd",target:"_blank",rel:"noopener noreferrer"}},[t._v("ajeetd"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-3-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-3-4"}},[t._v("#")]),t._v(" 3.3.4")]),t._v(" "),e("ul",[e("li",[t._v("Added support for masking fields in objects via "),e("code",[t._v("secret")]),t._v(" function:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendPostRequest")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/auth'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("secret")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'jon'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("password")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'123456'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Added "),e("a",{attrs:{href:"/secrets"}},[t._v("a guide about using of "),e("code",[t._v("secret")])]),t._v(" function")]),t._v(" "),e("li",[e("strong",[t._v("[Appium]")]),t._v(" Use "),e("code",[t._v("touchClick")]),t._v(" when interacting with elements in iOS. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3317",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3317"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/mikk150",target:"_blank",rel:"noopener noreferrer"}},[t._v("mikk150"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Added "),e("code",[t._v("cdpConnection")]),t._v(" option to connect over CDP. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3309",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3309"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Hmihaly",target:"_blank",rel:"noopener noreferrer"}},[t._v("Hmihaly"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[customLocator plugin] Allowed to specify multiple attributes for custom locator. Thanks to "),e("strong",[e("a",{attrs:{href:"https://github.com/aruiz-caritsqa",target:"_blank",rel:"noopener noreferrer"}},[t._v("aruiz-caritsqa"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("plugins")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("customLocator")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("enabled")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("prefix")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'$'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("attribute")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'data-qa'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'data-test'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("ul",[e("li",[t._v("[retryTo plugin] Fixed "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3147",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3147"),e("OutboundLink")],1),t._v(" using "),e("code",[t._v("pollInterval")]),t._v(" option. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3351",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3351"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/cyonkee",target:"_blank",rel:"noopener noreferrer"}},[t._v("cyonkee"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Fixed grabbing of browser console messages and window resize in new tab. Thanks to "),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[REST]")]),t._v(" Added "),e("code",[t._v("prettyPrintJson")]),t._v(" option to print JSON in nice way by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[JSONResponse]")]),t._v(" Updated response validation to iterate over array items if response is array. Thanks to "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// response.data == [")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// { user: { name: 'jon', email: 'jon@doe.com' } },")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// { user: { name: 'matt', email: 'matt@doe.com' } },")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//]")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseContainsKeys")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseContainsJson")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("email")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'jon@doe.com'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeResponseContainsJson")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("email")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'matt@doe.com'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeResponseContainsJson")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h2",{attrs:{id:"_3-3-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-3-3"}},[t._v("#")]),t._v(" 3.3.3")]),t._v(" "),e("ul",[e("li",[t._v("Fixed "),e("code",[t._v("DataCloneError: () => could not be cloned")]),t._v(" when running data tests in run-workers")]),t._v(" "),e("li",[t._v("🇺🇦 Added #StandWithUkraine notice to CLI")])]),t._v(" "),e("h2",{attrs:{id:"_3-3-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-3-2"}},[t._v("#")]),t._v(" 3.3.2")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[REST]")]),t._v(" Fixed override of headers/token in "),e("code",[t._v("haveRequestHeaders()")]),t._v(" and "),e("code",[t._v("amBearerAuthenticated()")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3304",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3304"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Reverted typings change introduced in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3245",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3245"),e("OutboundLink")],1),t._v(". "),e("a",{attrs:{href:"https://twitter.com/CodeceptJS/status/1519725963856207873",target:"_blank",rel:"noopener noreferrer"}},[t._v("More details on this"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_3-3-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-3-1"}},[t._v("#")]),t._v(" 3.3.1")]),t._v(" "),e("p",[t._v("🛩️ Features:")]),t._v(" "),e("ul",[e("li",[t._v("Add option to avoid duplicate gherkin step definitions ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3257",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3257"),e("OutboundLink")],1),t._v(") - "),e("strong",[e("a",{attrs:{href:"https://github.com/raywiis",target:"_blank",rel:"noopener noreferrer"}},[t._v("raywiis"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("step.*")]),t._v(" for run-workers "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3272",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3272"),e("OutboundLink")],1),t._v(". Thanks to "),e("strong",[e("a",{attrs:{href:"https://github.com/abhimanyupandian",target:"_blank",rel:"noopener noreferrer"}},[t._v("abhimanyupandian"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed loading tests for "),e("code",[t._v("codecept run")]),t._v(" using glob patterns. By "),e("strong",[e("a",{attrs:{href:"https://github.com/jayudey-wf",target:"_blank",rel:"noopener noreferrer"}},[t._v("jayudey-wf"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('npx codeceptjs run test-dir/*"\n')])])]),e("ul",[e("li",[e("strong",[t._v("[Playwright]")]),t._v(" "),e("strong",[t._v("Possible breaking change.")]),t._v(" By default "),e("code",[t._v("timeout")]),t._v(" is changed to 5000ms. The value set in 3.3.0 was too low. Please set "),e("code",[t._v("timeout")]),t._v(" explicitly to not depend on release values.")]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Added for color scheme option by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Playwright")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://localhost"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("colorScheme")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"dark"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("🐛 Bugfixes:")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Fixed "),e("code",[t._v("Cannot read property 'video' of undefined")])]),t._v(" "),e("li",[t._v("Fixed haveRequestHeaders() and amBearerAuthenticated() of REST helper ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3260",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3260"),e("OutboundLink")],1),t._v(") - "),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed: allure attachment fails if screenshot failed "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3298",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3298"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/ruudvanderweijde",target:"_blank",rel:"noopener noreferrer"}},[t._v("ruudvanderweijde"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3105",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3105"),e("OutboundLink")],1),t._v(" using autoLogin() plugin with TypeScript. Fix "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3290",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3290"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Added extra params for click and dragAndDrop to type definitions by "),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("📖 Documentation")]),t._v(" "),e("ul",[e("li",[t._v("Improving the typings in many places")]),t._v(" "),e("li",[t._v("Improving the return type of helpers for TS users ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3245",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3245"),e("OutboundLink")],1),t._v(") - "),e("strong",[e("a",{attrs:{href:"https://github.com/nlespiaucq",target:"_blank",rel:"noopener noreferrer"}},[t._v("nlespiaucq"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-3-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-3-0"}},[t._v("#")]),t._v(" 3.3.0")]),t._v(" "),e("p",[t._v("🛩️ Features:")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"/api"}},[e("strong",[t._v("API Testing introduced")])]),t._v(" "),e("ul",[e("li",[t._v("Introduced "),e("a",{attrs:{href:"/helpers/JSONResponse"}},[e("code",[t._v("JSONResponse")])]),t._v(" helper which connects to REST, GraphQL or Playwright helper")]),t._v(" "),e("li",[e("strong",[t._v("[REST]")]),t._v(" Added "),e("code",[t._v("amBearerAuthenticated")]),t._v(" method")]),t._v(" "),e("li",[e("strong",[t._v("[REST]")]),t._v(" Added "),e("code",[t._v("haveRequestHeaders")]),t._v(" method")]),t._v(" "),e("li",[t._v("Added dependency on "),e("code",[t._v("joi")]),t._v(" and "),e("code",[t._v("chai")])])])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Added "),e("code",[t._v("timeout")]),t._v(" option to set "),e("a",{attrs:{href:"https://playwright.dev/docs/api/class-page#page-set-default-timeout",target:"_blank",rel:"noopener noreferrer"}},[t._v("timeout"),e("OutboundLink")],1),t._v(" for all Playwright actions. If an action fails, Playwright keeps retrying it for a time set by timeout.")]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" "),e("strong",[t._v("Possible breaking change.")]),t._v(" By default "),e("code",[t._v("timeout")]),t._v(" is set to 1000ms. "),e("em",[t._v("Previous default was set by Playwright internally to 30s. This was causing contradiction to CodeceptJS retries, so triggered up to 3 retries for 30s of time. This timeout option was lowered so retryFailedStep plugin would not cause long delays.")])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Updated "),e("code",[t._v("restart")]),t._v(" config option to include 3 restart strategies:\n"),e("ul",[e("li",[t._v("'context' or "),e("strong",[t._v("false")]),t._v(" - restarts "),e("a",{attrs:{href:"https://playwright.dev/docs/api/class-browsercontext",target:"_blank",rel:"noopener noreferrer"}},[t._v("browser context"),e("OutboundLink")],1),t._v(" but keeps running browser. Recommended by Playwright team to keep tests isolated.")]),t._v(" "),e("li",[t._v("'browser' or "),e("strong",[t._v("true")]),t._v(" - closes browser and opens it again between tests.")]),t._v(" "),e("li",[t._v("'session' or 'keep' - keeps browser context and session, but cleans up cookies and localStorage between tests. The fastest option when running tests in windowed mode. Works with "),e("code",[t._v("keepCookies")]),t._v(" and "),e("code",[t._v("keepBrowserState")]),t._v(" options. This behavior was default prior CodeceptJS 3.1")])])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Extended methods to provide more options from engine. These methods were updated so additional options can be be passed as the last argument:\n"),e("ul",[e("li",[e("a",{attrs:{href:"/helpers/Playwright#click"}},[e("code",[t._v("click")])])]),t._v(" "),e("li",[e("a",{attrs:{href:"/helpers/Playwright#dragAndDrop"}},[e("code",[t._v("dragAndDrop")])])]),t._v(" "),e("li",[e("a",{attrs:{href:"/helpers/Playwright#checkOption"}},[e("code",[t._v("checkOption")])])]),t._v(" "),e("li",[e("a",{attrs:{href:"/helpers/Playwright#uncheckOption"}},[e("code",[t._v("uncheckOption")])])])])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// use Playwright click options as 3rd argument")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'canvas'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.model'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("position")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("x")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("y")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("40")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// check option also has options")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("checkOption")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Agree'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.signup'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("position")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("x")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("y")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("ul",[e("li",[e("code",[t._v("eachElement")]),t._v(" plugin introduced. It allows you to iterate over elements and perform some action on them using direct engines API")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("eachElement")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'click all links in .list'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.list a'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("el")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" el"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("ul",[e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Added support to "),e("code",[t._v("playwright-core")]),t._v(" package if "),e("code",[t._v("playwright")]),t._v(" is not installed. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3190",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3190"),e("OutboundLink")],1),t._v(", fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2663",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2663"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Added "),e("code",[t._v("makeApiRequest")]),t._v(" action to perform API requests. Requires Playwright >= 1.18")]),t._v(" "),e("li",[t._v("Added support to "),e("code",[t._v("codecept.config.js")]),t._v(" for name consistency across other JS tools. See motivation at "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3195",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3195"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/JiLiZART",target:"_blank",rel:"noopener noreferrer"}},[t._v("JiLiZART"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[ApiDataFactory]")]),t._v(" Added options arg to "),e("code",[t._v("have")]),t._v(" method. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3197",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3197"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/JJlokidoki",target:"_blank",rel:"noopener noreferrer"}},[t._v("JJlokidoki"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Improved pt-br translations to include keywords: 'Funcionalidade', 'Cenário', 'Antes', 'Depois', 'AntesDaSuite', 'DepoisDaSuite'. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3206",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3206"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/danilolutz",target:"_blank",rel:"noopener noreferrer"}},[t._v("danilolutz"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[allure plugin] Introduced "),e("code",[t._v("addStep")]),t._v(" method to add comments and attachments. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3104",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3104"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/EgorBodnar",target:"_blank",rel:"noopener noreferrer"}},[t._v("EgorBodnar"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("🐛 Bugfixes:")]),t._v(" "),e("ul",[e("li",[t._v("Fixed "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3212",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3212"),e("OutboundLink")],1),t._v(": using Regex flags for Cucumber steps. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3214",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3214"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/anils92",target:"_blank",rel:"noopener noreferrer"}},[t._v("anils92"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("📖 Documentation")]),t._v(" "),e("ul",[e("li",[t._v("Added "),e("a",{attrs:{href:"/reports#testomatio"}},[t._v("Testomat.io reporter")])]),t._v(" "),e("li",[t._v("Added "),e("a",{attrs:{href:"/api"}},[t._v("api testing")]),t._v(" guides")]),t._v(" "),e("li",[t._v("Added "),e("a",{attrs:{href:"/internal-api"}},[t._v("internal api")]),t._v(" guides")]),t._v(" "),e("li",[e("strong",[t._v("[Appium]")]),t._v(" Fixed documentation for "),e("code",[t._v("performSwipe")])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" update docs for "),e("code",[t._v("usePlaywrightTo")]),t._v(" method by "),e("strong",[e("a",{attrs:{href:"https://github.com/dbudzins",target:"_blank",rel:"noopener noreferrer"}},[t._v("dbudzins"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-2-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-3"}},[t._v("#")]),t._v(" 3.2.3")]),t._v(" "),e("ul",[e("li",[t._v("Documentation improvements by "),e("strong",[e("a",{attrs:{href:"https://github.com/maojunxyz",target:"_blank",rel:"noopener noreferrer"}},[t._v("maojunxyz"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Guard mocha cli reporter from registering step logger multiple times "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3180",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3180"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/nikocanvacom",target:"_blank",rel:"noopener noreferrer"}},[t._v("nikocanvacom"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(' Fixed "tracing.stop: tracing.stop: ENAMETOOLONG: name too long" by '),e("strong",[e("a",{attrs:{href:"https://github.com/hatufacci",target:"_blank",rel:"noopener noreferrer"}},[t._v("hatufacci"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2889",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2889"),e("OutboundLink")],1),t._v(": return always the same error contract from simplifyTest. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3168",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3168"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/andremoah",target:"_blank",rel:"noopener noreferrer"}},[t._v("andremoah"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-2-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-2"}},[t._v("#")]),t._v(" 3.2.2")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Reverted removal of retry on context errors. Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3130",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3130"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Timeout improvements by "),e("strong",[e("a",{attrs:{href:"https://github.com/nikocanvacom",target:"_blank",rel:"noopener noreferrer"}},[t._v("nikocanvacom"),e("OutboundLink")],1)]),t._v(":\n"),e("ul",[e("li",[t._v("Added priorites to timeouts")]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("overrideStepLimits")]),t._v(" to "),e("a",{attrs:{href:"https://codecept.io/plugins/#steptimeout",target:"_blank",rel:"noopener noreferrer"}},[t._v("stepTimeout plugin"),e("OutboundLink")],1),t._v(" to override steps timeouts set by "),e("code",[t._v("limitTime")]),t._v(".")]),t._v(" "),e("li",[t._v("Fixed step timeout not working due to override by NaN by test timeout "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3126",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3126"),e("OutboundLink")],1)])])]),t._v(" "),e("li",[e("strong",[t._v("[Appium]")]),t._v(" Fixed logging error when "),e("code",[t._v("manualStart")]),t._v(" is true. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3140",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3140"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/nikocanvacom",target:"_blank",rel:"noopener noreferrer"}},[t._v("nikocanvacom"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-2-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-1"}},[t._v("#")]),t._v(" 3.2.1")]),t._v(" "),e("blockquote",[e("p",[t._v("♻️ This release fixes hanging of tests by reducing timeouts for automatic retries on failures.")])]),t._v(" "),e("ul",[e("li",[t._v("[retryFailedStep plugin] "),e("strong",[t._v("New Defaults")]),t._v(": retries steps up to 3 times with factor of 1.5 (previously 5 with factor 2)")]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" - disabled retry on failed context actions (not needed anymore)")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" - reduced retries on context failures to 3 times.")]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Handling "),e("code",[t._v("crash")]),t._v(" event to automatically close crashed pages.")])]),t._v(" "),e("h2",{attrs:{id:"_3-2-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-2-0"}},[t._v("#")]),t._v(" 3.2.0")]),t._v(" "),e("p",[t._v("🛩️ Features:")]),t._v(" "),e("p",[e("strong",[e("a",{attrs:{href:"https://codecept.io/advanced/#timeout",target:"_blank",rel:"noopener noreferrer"}},[t._v("Timeouts"),e("OutboundLink")],1),t._v(" implemented")])]),t._v(" "),e("ul",[e("li",[t._v("global timeouts (via "),e("code",[t._v("timeout")]),t._v(" config option).\n"),e("ul",[e("li",[e("em",[t._v("Breaking change:")]),t._v(" timeout option expects "),e("strong",[t._v("timeout in seconds")]),t._v(", not in milliseconds as it was previously.")])])]),t._v(" "),e("li",[t._v("test timeouts (via "),e("code",[t._v("Scenario")]),t._v(" and "),e("code",[t._v("Feature")]),t._v(" options)\n"),e("ul",[e("li",[e("em",[t._v("Breaking change:")]),t._v(" "),e("code",[t._v("Feature().timeout()")]),t._v(" and "),e("code",[t._v("Scenario().timeout()")]),t._v(" calls has no effect and are deprecated")])])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// set timeout for every test in suite to 10 secs")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'tests with timeout'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("timeout")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// set timeout for this test to 20 secs")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'a test with timeout'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("timeout")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[t._v("step timeouts (See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3059",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3059"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/nikocanvacom",target:"_blank",rel:"noopener noreferrer"}},[t._v("nikocanvacom"),e("OutboundLink")],1)]),t._v(")")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// set step timeout to 5 secs")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("limitTime")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Link'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("code",[t._v("stepTimeout")]),t._v(" plugin introduced to automatically add timeouts for each step ("),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3059",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3059"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/nikocanvacom",target:"_blank",rel:"noopener noreferrer"}},[t._v("nikocanvacom"),e("OutboundLink")],1)]),t._v(").")])]),t._v(" "),e("p",[e("RouterLink",{attrs:{to:"/plugins/#retryto"}},[e("strong",[t._v("retryTo")])]),t._v(" plugin introduced to rerun a set of steps on failure:")],1),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// editing in text in iframe")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// if iframe was not loaded - retry 5 times")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("retryTo")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("switchTo")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#editor frame'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'textarea'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'value'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("strong",[t._v("[Playwright]")]),t._v(" added "),e("code",[t._v("locale")]),t._v(" configuration")]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" upgraded to webdriverio v7")])]),t._v(" "),e("p",[t._v("🐛 Bugfixes:")]),t._v(" "),e("ul",[e("li",[t._v('Fixed allure plugin "Unexpected endStep()" error in '),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3098",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3098"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/abhimanyupandian",target:"_blank",rel:"noopener noreferrer"}},[t._v("abhimanyupandian"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" always close remote browser on test end. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3054",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3054"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/mattonem",target:"_blank",rel:"noopener noreferrer"}},[t._v("mattonem"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("stepbyStepReport Plugin: Disabled screenshots after test has failed. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3119",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3119"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/ioannisChalkias",target:"_blank",rel:"noopener noreferrer"}},[t._v("ioannisChalkias"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-1-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-1-3"}},[t._v("#")]),t._v(" 3.1.3")]),t._v(" "),e("p",[t._v("🛩️ Features:")]),t._v(" "),e("ul",[e("li",[t._v("BDD Improvement. Added "),e("code",[t._v("DataTableArgument")]),t._v(" class to work with table data structures.")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" DataTableArgument "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'codeceptjs'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//...")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Given")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I have an employee card'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("table")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" dataTableArgument "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DataTableArgument")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("table"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" hashes "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" dataTableArgument"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("hashes")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" \n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// hashes = [{ name: 'Harry', surname: 'Potter', position: 'Seeker' }];")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" rows "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" dataTableArgument"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("rows")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// rows = [['Harry', 'Potter', Seeker]];")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("See updated "),e("a",{attrs:{href:"https://codecept.io/bdd/",target:"_blank",rel:"noopener noreferrer"}},[t._v("BDD section"),e("OutboundLink")],1),t._v(" for more API options. Thanks to "),e("strong",[e("a",{attrs:{href:"https://github.com/EgorBodnar",target:"_blank",rel:"noopener noreferrer"}},[t._v("EgorBodnar"),e("OutboundLink")],1)])]),t._v(" "),e("ul",[e("li",[t._v("Support "),e("code",[t._v("cjs")]),t._v(" file extensions for config file: "),e("code",[t._v("codecept.conf.cjs")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3052",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3052"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/kalvenschraut",target:"_blank",rel:"noopener noreferrer"}},[t._v("kalvenschraut"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("API updates: Added "),e("code",[t._v("test.file")]),t._v(" and "),e("code",[t._v("suite.file")]),t._v(" properties to "),e("code",[t._v("test")]),t._v(" and "),e("code",[t._v("suite")]),t._v(" objects to use in helpers and plugins.")])]),t._v(" "),e("p",[t._v("🐛 Bugfixes:")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Fixed resetting "),e("code",[t._v("test.artifacts")]),t._v(" for failing tests. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3033",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3033"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/jancorvus",target:"_blank",rel:"noopener noreferrer"}},[t._v("jancorvus"),e("OutboundLink")],1)]),t._v(". Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3032",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3032"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Apply "),e("code",[t._v("basicAuth")]),t._v(" credentials to all opened browser contexts. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3036",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3036"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/nikocanvacom",target:"_blank",rel:"noopener noreferrer"}},[t._v("nikocanvacom"),e("OutboundLink")],1)]),t._v(". Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3035",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3035"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Updated "),e("code",[t._v("webdriverio")]),t._v(" default version to "),e("code",[t._v("^6.12.1")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3043",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3043"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/sridhareaswaran",target:"_blank",rel:"noopener noreferrer"}},[t._v("sridhareaswaran"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" "),e("code",[t._v("I.haveRequestHeaders")]),t._v(" affects all tabs. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3049",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3049"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/jancorvus",target:"_blank",rel:"noopener noreferrer"}},[t._v("jancorvus"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("BDD: Fixed unhandled empty feature files. Fix "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3046",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3046"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/abhimanyupandian",target:"_blank",rel:"noopener noreferrer"}},[t._v("abhimanyupandian"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed "),e("code",[t._v("RangeError: Invalid string length")]),t._v(" in "),e("code",[t._v("recorder.js")]),t._v(" when running huge amount of tests.")]),t._v(" "),e("li",[e("strong",[t._v("[Appium]")]),t._v(" Fixed definitions for "),e("code",[t._v("touchPerform")]),t._v(", "),e("code",[t._v("hideDeviceKeyboard")]),t._v(", "),e("code",[t._v("removeApp")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("📖 Documentation:")]),t._v(" "),e("ul",[e("li",[t._v("Added Testrail reporter "),e("a",{attrs:{href:"https://codecept.io/reports/#testrail",target:"_blank",rel:"noopener noreferrer"}},[t._v("Reports Docs"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_3-1-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-1-2"}},[t._v("#")]),t._v(" 3.1.2")]),t._v(" "),e("p",[t._v("🛩️ Features:")]),t._v(" "),e("ul",[e("li",[t._v("Added "),e("code",[t._v("coverage")]),t._v(" plugin to generate code coverage for Playwright & Puppeteer. By "),e("strong",[e("a",{attrs:{href:"https://github.com/anirudh-modi",target:"_blank",rel:"noopener noreferrer"}},[t._v("anirudh-modi"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("subtitle")]),t._v(" plugin to generate subtitles for videos recorded with Playwright. By "),e("strong",[e("a",{attrs:{href:"https://github.com/anirudh-modi",target:"_blank",rel:"noopener noreferrer"}},[t._v("anirudh-modi"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Configuration: "),e("code",[t._v("config.tests")]),t._v(" to accept array of file patterns. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2994",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2994"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/monsteramba",target:"_blank",rel:"noopener noreferrer"}},[t._v("monsteramba"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[t._v("exports"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("tests")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./*_test.js'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./sampleTest.js'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ... ")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Notification is shown for test files without "),e("code",[t._v("Feature()")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3011",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3011"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("🐛 Bugfixes:")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Fixed "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2986",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2986"),e("OutboundLink")],1),t._v(" error is thrown when deleting a missing video. Fix by "),e("strong",[e("a",{attrs:{href:"https://github.com/hatufacci",target:"_blank",rel:"noopener noreferrer"}},[t._v("hatufacci"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed false positive result when invalid function is called in a helper. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2997",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2997"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/abhimanyupandian",target:"_blank",rel:"noopener noreferrer"}},[t._v("abhimanyupandian"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Appium]")]),t._v(" Removed full page mode for "),e("code",[t._v("saveScreenshot")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3002",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3002"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/nlespiaucq",target:"_blank",rel:"noopener noreferrer"}},[t._v("nlespiaucq"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Fixed "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/3003",target:"_blank",rel:"noopener noreferrer"}},[t._v("#3003"),e("OutboundLink")],1),t._v(" saving trace for a test with a long name. Fix by "),e("strong",[e("a",{attrs:{href:"https://github.com/hatufacci",target:"_blank",rel:"noopener noreferrer"}},[t._v("hatufacci"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("🎱 Other:")]),t._v(" "),e("ul",[e("li",[t._v("Deprecated "),e("code",[t._v("puppeteerCoverage")]),t._v(" plugin in favor of "),e("code",[t._v("coverage")]),t._v(" plugin.")])]),t._v(" "),e("h2",{attrs:{id:"_3-1-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-1-1"}},[t._v("#")]),t._v(" 3.1.1")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Appium]")]),t._v(" Fixed "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2759",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2759"),e("OutboundLink")],1),t._v(" "),e("code",[t._v("grabNumberOfVisibleElements")]),t._v(", "),e("code",[t._v("grabAttributeFrom")]),t._v(", "),e("code",[t._v("grabAttributeFromAll")]),t._v(" to allow id locators.")])]),t._v(" "),e("h2",{attrs:{id:"_3-1-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-1-0"}},[t._v("#")]),t._v(" 3.1.0")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Plawyright]")]),t._v(" Updated to Playwright 1.13")]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" "),e("strong",[t._v("Possible breaking change")]),t._v(": "),e("code",[t._v("BrowserContext")]),t._v(" is initialized before each test and closed after. This behavior matches recommendation from Playwright team to use different contexts for tests.")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Updated to Puppeteer 10.2.")]),t._v(" "),e("li",[e("strong",[t._v("[Protractor]")]),t._v(" Helper deprecated")])]),t._v(" "),e("p",[t._v("🛩️ Features:")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Added recording of "),e("a",{attrs:{href:"https://codecept.io/playwright/#video",target:"_blank",rel:"noopener noreferrer"}},[t._v("video"),e("OutboundLink")],1),t._v(" and "),e("a",{attrs:{href:"https://codecept.io/playwright/#trace",target:"_blank",rel:"noopener noreferrer"}},[t._v("traces"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwritght]")]),t._v(" "),e("a",{attrs:{href:"https://codecept.io/playwright/#mocking-network-requests",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mocking requests"),e("OutboundLink")],1),t._v(" implemented via "),e("code",[t._v("route")]),t._v(" API of Playwright by "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Added "),e("strong",[t._v("support for "),e("a",{attrs:{href:"https://codecept.io/react/#locators",target:"_blank",rel:"noopener noreferrer"}},[t._v("React locators"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2912",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2912"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/AAAstorga",target:"_blank",rel:"noopener noreferrer"}},[t._v("AAAstorga"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("🐛 Bugfixes:")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2244",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2244"),e("OutboundLink")],1),t._v(" "),e("code",[t._v("els[0]._clickablePoint is not a function")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/karunandrii",target:"_blank",rel:"noopener noreferrer"}},[t._v("karunandrii"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed "),e("code",[t._v("fillField")]),t._v(" to check for invisible elements. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2916",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2916"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/anne-open-xchange",target:"_blank",rel:"noopener noreferrer"}},[t._v("anne-open-xchange"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Reset of dialog event listener before registration of new one. "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2946",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2946"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/nikocanvacom",target:"_blank",rel:"noopener noreferrer"}},[t._v("nikocanvacom"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed running Gherkin features with "),e("code",[t._v("run-multiple")]),t._v(" using chunks. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2900",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2900"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/andrenoberto",target:"_blank",rel:"noopener noreferrer"}},[t._v("andrenoberto"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2937",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2937"),e("OutboundLink")],1),t._v(" broken typings for subfolders on Windows by "),e("strong",[e("a",{attrs:{href:"https://github.com/jancorvus",target:"_blank",rel:"noopener noreferrer"}},[t._v("jancorvus"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed issue where cucumberJsonReporter not working with fakerTransform plugin. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2942",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2942"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/ilangv",target:"_blank",rel:"noopener noreferrer"}},[t._v("ilangv"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2952",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2952"),e("OutboundLink")],1),t._v(" finished job with status code 0 when playwright cannot connect to remote wss url. By "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-0-7"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-0-7"}},[t._v("#")]),t._v(" 3.0.7")]),t._v(" "),e("p",[t._v("📖 Documentation fixes:")]),t._v(" "),e("ul",[e("li",[t._v("Remove broken link from "),e("code",[t._v("Nightmare helper")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2860",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2860"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Arhell",target:"_blank",rel:"noopener noreferrer"}},[t._v("Arhell"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed broken links in "),e("code",[t._v("playwright.md")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2848",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2848"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/johnhoodjr",target:"_blank",rel:"noopener noreferrer"}},[t._v("johnhoodjr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fix mocha-multi config example. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2881",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2881"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/rimesc",target:"_blank",rel:"noopener noreferrer"}},[t._v("rimesc"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fix small errors in email documentation file. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2884",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2884"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/mkrtchian",target:"_blank",rel:"noopener noreferrer"}},[t._v("mkrtchian"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Improve documentation for "),e("code",[t._v("Sharing Data Between Workers")]),t._v(" section. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2891",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2891"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/ngraf",target:"_blank",rel:"noopener noreferrer"}},[t._v("ngraf"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("🛩️ Features:")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Shadow DOM Support for "),e("code",[t._v("Webdriver")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2741",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2741"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/gkushang",target:"_blank",rel:"noopener noreferrer"}},[t._v("gkushang"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[Release management] Introduce the versioning automatically, it follows the semantics versioning. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2883",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2883"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Adding opts into "),e("code",[t._v("Scenario.skip")]),t._v(" that it would be useful for building reports. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2867",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2867"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/AlexKo4",target:"_blank",rel:"noopener noreferrer"}},[t._v("AlexKo4"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added support for attaching screenshots to "),e("a",{attrs:{href:"https://github.com/ktryniszewski-mdsol/codeceptjs-cucumber-json-reporter",target:"_blank",rel:"noopener noreferrer"}},[t._v("cucumberJsonReporter"),e("OutboundLink")],1),t._v(" See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2888",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2888"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/fijijavis",target:"_blank",rel:"noopener noreferrer"}},[t._v("fijijavis"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Supported config file for "),e("code",[t._v("codeceptjs shell")]),t._v(" command. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2895",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2895"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(":")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("npx codeceptjs shell -c foo.conf.js\n")])])]),e("p",[t._v("Bug fixes:")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[GraphQL]")]),t._v(" Use a helper-specific instance of Axios to avoid contaminating global defaults. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2868",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2868"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/vanvoljg",target:"_blank",rel:"noopener noreferrer"}},[t._v("vanvoljg"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("A default system color is used when passing non supported system color when using I.say(). See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2874",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2874"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Avoid the timout due to calling the click on invisible elements. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2875",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2875"),e("OutboundLink")],1),t._v(" by cbayer97")])]),t._v(" "),e("h2",{attrs:{id:"_3-0-6"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-0-6"}},[t._v("#")]),t._v(" 3.0.6")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Added "),e("code",[t._v("electron")]),t._v(" as a browser to config. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2834",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2834"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/cbayer97",target:"_blank",rel:"noopener noreferrer"}},[t._v("cbayer97"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Implemented "),e("code",[t._v("launchPersistentContext")]),t._v(" to be able to launch persistent remote browsers. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2817",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2817"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/brunoqueiros",target:"_blank",rel:"noopener noreferrer"}},[t._v("brunoqueiros"),e("OutboundLink")],1)]),t._v(". Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2376",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2376"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[t._v("Fixed printing logs and stack traces for "),e("code",[t._v("run-workers")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2857",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2857"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/haveac1gar",target:"_blank",rel:"noopener noreferrer"}},[t._v("haveac1gar"),e("OutboundLink")],1)]),t._v(". Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2621",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2621"),e("OutboundLink")],1),t._v(", "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2852",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2852"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Emit custom messages from worker to the main thread. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2824",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2824"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/jccguimaraes",target:"_blank",rel:"noopener noreferrer"}},[t._v("jccguimaraes"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Improved workers processes output. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2804",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2804"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/drfiresign",target:"_blank",rel:"noopener noreferrer"}},[t._v("drfiresign"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("BDD. Added ability to use an array of feature files inside config in "),e("code",[t._v("gherkin.features")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2814",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2814"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/jbergeronjr",target:"_blank",rel:"noopener noreferrer"}},[t._v("jbergeronjr"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"features"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./features/*.feature"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./features/api_features/*.feature"')]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Added "),e("code",[t._v("getQueueId")]),t._v(" to reporter to rerun a specific promise. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2837",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2837"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/jonatask",target:"_blank",rel:"noopener noreferrer"}},[t._v("jonatask"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("Added "),e("code",[t._v("fakerTransform")]),t._v(" plugin")]),t._v(" to use faker data in Gherkin scenarios. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2854",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2854"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/adrielcodeco",target:"_blank",rel:"noopener noreferrer"}},[t._v("adrielcodeco"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language-feature extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("Scenario Outline: ...\n Given ...\n When ...\n Then ...\n\n Examples:\n | productName | customer | email | anythingMore |\n | {{commerce.product}} | Dr. {{name.findName}} | {{internet.email}} | staticData |\n")])])]),e("ul",[e("li",[e("strong",[t._v("[REST]")]),t._v(" Use class instance of axios, not the global instance, to avoid contaminating global configuration. "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2846",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2846"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/vanvoljg",target:"_blank",rel:"noopener noreferrer"}},[t._v("vanvoljg"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Appium]")]),t._v(" Added "),e("code",[t._v("tunnelIdentifier")]),t._v(" config option to provide tunnel for SauceLabs. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2832",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2832"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/gurjeetbains",target:"_blank",rel:"noopener noreferrer"}},[t._v("gurjeetbains"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-0-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-0-5"}},[t._v("#")]),t._v(" 3.0.5")]),t._v(" "),e("p",[t._v("Features:")]),t._v(" "),e("ul",[e("li",[e("strong",[e("a",{attrs:{href:"https://hub.docker.com/r/codeceptjs/codeceptjs",target:"_blank",rel:"noopener noreferrer"}},[t._v("Official Docker image for CodeceptJS v3"),e("OutboundLink")],1)]),t._v(". New Docker image is based on official Playwright image and supports Playwright, Puppeteer, WebDriver engines. Thanks "),e("strong",[e("a",{attrs:{href:"https://github.com/VikentyShevyrin",target:"_blank",rel:"noopener noreferrer"}},[t._v("VikentyShevyrin"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Better support for Typescript "),e("code",[t._v("codecept.conf.ts")]),t._v(" configuration files. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2750",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2750"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/elaichenkov",target:"_blank",rel:"noopener noreferrer"}},[t._v("elaichenkov"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Propagate more events for custom parallel script. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2796",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2796"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/jccguimaraes",target:"_blank",rel:"noopener noreferrer"}},[t._v("jccguimaraes"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[mocha-junit-reporter] Now supports attachments, see documentation for details. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2675",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2675"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Shard",target:"_blank",rel:"noopener noreferrer"}},[t._v("Shard"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("CustomLocators interface for TypeScript to extend from LocatorOrString. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2798",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2798"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/danielrentz",target:"_blank",rel:"noopener noreferrer"}},[t._v("danielrentz"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[REST]")]),t._v(" Mask sensitive data from log messages.")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendPatchRequest")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/users.json'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("secret")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"email"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"user@user.com"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2786",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2786"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("p",[t._v("Bug fixes:")]),t._v(" "),e("ul",[e("li",[t._v("Fixed reporting of nested steps with PageObjects and BDD scenarios. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2800",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2800"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)]),t._v(". Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2720",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2720"),e("OutboundLink")],1),t._v(" "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2682",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2682"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Fixed issue with "),e("code",[t._v("codeceptjs shell")]),t._v(" which was broken since 3.0.0. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2743",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2743"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/stedman",target:"_blank",rel:"noopener noreferrer"}},[t._v("stedman"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Gherkin]")]),t._v(" Fixed issue suppressed or hidden errors in tests. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2745",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2745"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/ktryniszewski-mdsol",target:"_blank",rel:"noopener noreferrer"}},[t._v("ktryniszewski-mdsol"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" fix grabCssPropertyFromAll serialization by using property names. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2757",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2757"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/elaichenkov",target:"_blank",rel:"noopener noreferrer"}},[t._v("elaichenkov"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Allure]")]),t._v(" fix report for multi sessions. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2771",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2771"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/cbayer97",target:"_blank",rel:"noopener noreferrer"}},[t._v("cbayer97"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Fix locator object debug log messages in smart wait. See 2748 by "),e("strong",[e("a",{attrs:{href:"https://github.com/elaichenkov",target:"_blank",rel:"noopener noreferrer"}},[t._v("elaichenkov"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("Documentation fixes:")]),t._v(" "),e("ul",[e("li",[t._v("Fixed some broken examples. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2756",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2756"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/danielrentz",target:"_blank",rel:"noopener noreferrer"}},[t._v("danielrentz"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed Typescript typings. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2747",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2747"),e("OutboundLink")],1),t._v(", "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2758",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2758"),e("OutboundLink")],1),t._v(" and "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2769",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2769"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/elaichenkov",target:"_blank",rel:"noopener noreferrer"}},[t._v("elaichenkov"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added missing type for xFeature. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2754",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2754"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed code example in Page Object documentation. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2793",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2793"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/mkrtchian",target:"_blank",rel:"noopener noreferrer"}},[t._v("mkrtchian"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("Library updates:")]),t._v(" "),e("ul",[e("li",[t._v("Updated Axios to 0.21.1. See by "),e("strong",[e("a",{attrs:{href:"https://github.com/sseide",target:"_blank",rel:"noopener noreferrer"}},[t._v("sseide"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Updated "),e("strong",[e("a",{attrs:{href:"https://github.com/pollyjs",target:"_blank",rel:"noopener noreferrer"}},[t._v("pollyjs"),e("OutboundLink")],1)]),t._v("/core "),e("strong",[e("a",{attrs:{href:"https://github.com/pollyjs",target:"_blank",rel:"noopener noreferrer"}},[t._v("pollyjs"),e("OutboundLink")],1)]),t._v("/adapter-puppeteer. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2760",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2760"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Anikethana",target:"_blank",rel:"noopener noreferrer"}},[t._v("Anikethana"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-0-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-0-4"}},[t._v("#")]),t._v(" 3.0.4")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Hotfix")]),t._v(" Fixed "),e("code",[t._v("init")]),t._v(" script by adding "),e("code",[t._v("cross-spawn")]),t._v(" package. By "),e("strong",[e("a",{attrs:{href:"https://github.com/vipulgupta2048",target:"_blank",rel:"noopener noreferrer"}},[t._v("vipulgupta2048"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed handling error during initialization of "),e("code",[t._v("run-multiple")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2730",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2730"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/wagoid",target:"_blank",rel:"noopener noreferrer"}},[t._v("wagoid"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-0-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-0-3"}},[t._v("#")]),t._v(" 3.0.3")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Playwright 1.7 support")])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Fixed handling null context in click. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2667",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2667"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/matthewjf",target:"_blank",rel:"noopener noreferrer"}},[t._v("matthewjf"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Fixed "),e("code",[t._v("Cannot read property '$$' of null")]),t._v(" when locating elements. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2713",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2713"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/matthewjf",target:"_blank",rel:"noopener noreferrer"}},[t._v("matthewjf"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Command "),e("code",[t._v("npx codeceptjs init")]),t._v(" improved\n"),e("ul",[e("li",[t._v("auto-installing required packages")]),t._v(" "),e("li",[t._v("better error messages")]),t._v(" "),e("li",[t._v("fixed generating type definitions")])])]),t._v(" "),e("li",[t._v("Data Driven Tests improvements: instead of having one skipped test for data driven scenarios when using xData you get a skipped test for each entry in the data table. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2698",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2698"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Georgegriff",target:"_blank",rel:"noopener noreferrer"}},[t._v("Georgegriff"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed that "),e("code",[t._v("waitForFunction")]),t._v(" was not working with number values. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2703",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2703"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/MumblesNZ",target:"_blank",rel:"noopener noreferrer"}},[t._v("MumblesNZ"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Enabled autocompletion for custom helpers. "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2695",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2695"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Emit test.after on workers. Fix "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2693",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2693"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/jccguimaraes",target:"_blank",rel:"noopener noreferrer"}},[t._v("jccguimaraes"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("TypeScript: Allow .ts config files. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2708",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2708"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/elukoyanov",target:"_blank",rel:"noopener noreferrer"}},[t._v("elukoyanov"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed definitions generation errors by "),e("strong",[e("a",{attrs:{href:"https://github.com/elukoyanov",target:"_blank",rel:"noopener noreferrer"}},[t._v("elukoyanov"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2707",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2707"),e("OutboundLink")],1),t._v(" and "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2718",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2718"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Fixed handing error in _after function; for example, browser is closed during test and tests executions is stopped, but error was not logged. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2715",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2715"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/elukoyanov",target:"_blank",rel:"noopener noreferrer"}},[t._v("elukoyanov"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Emit hook.failed in workers. Fix "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2723",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2723"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/jccguimaraes",target:"_blank",rel:"noopener noreferrer"}},[t._v("jccguimaraes"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[wdio plugin] Added "),e("code",[t._v("seleniumArgs")]),t._v(" and "),e("code",[t._v("seleniumInstallArgs")]),t._v(" config options for plugin. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2687",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2687"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/andrerleao",target:"_blank",rel:"noopener noreferrer"}},[t._v("andrerleao"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[allure plugin] Added "),e("code",[t._v("addParameter")]),t._v(" method in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2717",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2717"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/jancorvus",target:"_blank",rel:"noopener noreferrer"}},[t._v("jancorvus"),e("OutboundLink")],1)]),t._v(". Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2716",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2716"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Added mocha-based "),e("code",[t._v("--reporter-options")]),t._v(" and "),e("code",[t._v("--reporter ")]),t._v(" commands to "),e("code",[t._v("run-workers")]),t._v(" command by in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2691",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2691"),e("OutboundLink")],1),t._v(" "),e("strong",[e("a",{attrs:{href:"https://github.com/Ameterezu",target:"_blank",rel:"noopener noreferrer"}},[t._v("Ameterezu"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed infinite loop for junit reports. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2691",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2691"),e("OutboundLink")],1),t._v(" "),e("strong",[e("a",{attrs:{href:"https://github.com/Ameterezu",target:"_blank",rel:"noopener noreferrer"}},[t._v("Ameterezu"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added status, start/end time, and match line for BDD steps. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2678",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2678"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/ktryniszewski-mdsol",target:"_blank",rel:"noopener noreferrer"}},[t._v("ktryniszewski-mdsol"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v('[stepByStepReport plugin] Fixed "helper.saveScreenshot is not a function". Fix '),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2688",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2688"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/andrerleao",target:"_blank",rel:"noopener noreferrer"}},[t._v("andrerleao"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_3-0-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-0-2"}},[t._v("#")]),t._v(" 3.0.2")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Fix connection close with remote browser. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2629",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2629"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/dipiash",target:"_blank",rel:"noopener noreferrer"}},[t._v("dipiash"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[REST]")]),t._v(" set maxUploadFileSize when performing api calls. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2611",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2611"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Duplicate Scenario names (combined with Feature name) are now detected via a warning message.\nDuplicate test names can cause "),e("code",[t._v("codeceptjs run-workers")]),t._v(" to not function. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2656",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2656"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Georgegriff",target:"_blank",rel:"noopener noreferrer"}},[t._v("Georgegriff"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Documentation fixes")])]),t._v(" "),e("p",[t._v("Bug Fixes:")]),t._v(" "),e("ul",[e("li",[t._v("--suites flag now should function correctly for "),e("code",[t._v("codeceptjs run-workers")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2655",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2655"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Georgegriff",target:"_blank",rel:"noopener noreferrer"}},[t._v("Georgegriff"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[autoLogin plugin] Login methods should now function as expected with "),e("code",[t._v("codeceptjs run-workers")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2658",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2658"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Georgegriff",target:"_blank",rel:"noopener noreferrer"}},[t._v("Georgegriff"),e("OutboundLink")],1)]),t._v(", resolves "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2620",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2620"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_3-0-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-0-1"}},[t._v("#")]),t._v(" 3.0.1")]),t._v(" "),e("p",[t._v("♨️ Hot fix:")]),t._v(" "),e("ul",[e("li",[t._v("Lock the mocha version to avoid the errors. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2624",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2624"),e("OutboundLink")],1),t._v(" by PeterNgTr")])]),t._v(" "),e("p",[t._v("🐛 Bug Fix:")]),t._v(" "),e("ul",[e("li",[e("p",[t._v("Fixed error handling in Scenario.js. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2607",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2607"),e("OutboundLink")],1),t._v(" by haveac1gar")])]),t._v(" "),e("li",[e("p",[t._v("Changing type definition in order to allow the use of functions with any number of any arguments. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2616",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2616"),e("OutboundLink")],1),t._v(" by akoltun")])]),t._v(" "),e("li",[e("p",[t._v("Some updates/changes on documentations")])])]),t._v(" "),e("h2",{attrs:{id:"_3-0-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-0-0"}},[t._v("#")]),t._v(" 3.0.0")]),t._v(" "),e("blockquote",[e("p",[e("a",{attrs:{href:"https://bit.ly/codecept3Up",target:"_blank",rel:"noopener noreferrer"}},[t._v(" 👌 "),e("strong",[t._v("LEARN HOW TO UPGRADE TO CODECEPTJS 3 ➡")]),e("OutboundLink")],1)])]),t._v(" "),e("ul",[e("li",[t._v("Playwright set to be a default engine.")]),t._v(" "),e("li",[e("strong",[t._v("NodeJS 12+ required")])]),t._v(" "),e("li",[e("strong",[t._v("BREAKING CHANGE:")]),t._v(" Syntax for tests has changed.")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Previous")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'title'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" loginPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Current")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'title'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" loginPage "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("strong",[t._v("BREAKING")]),t._v(" Replaced bootstrap/teardown scripts to accept only functions or async functions. Async function with callback (with done parameter) should be replaced with async/await. "),e("a",{attrs:{href:"https://bit.ly/codecept3Up",target:"_blank",rel:"noopener noreferrer"}},[t._v("See our upgrade guide"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[e("strong",[e("a",{attrs:{href:"/typescript"}},[t._v("TypeScript guide")])]),t._v(" and "),e("a",{attrs:{href:"https://github.com/codeceptjs/typescript-boilerplate",target:"_blank",rel:"noopener noreferrer"}},[t._v("boilerplate project"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("RouterLink",{attrs:{to:"/plugins/#tryto"}},[t._v("tryTo")]),t._v(" and "),e("RouterLink",{attrs:{to:"/plugins/#pauseOnFail"}},[t._v("pauseOnFail")]),t._v(" plugins installed by default")],1),t._v(" "),e("li",[t._v("Introduced one-line installer:")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("npx create-codeceptjs .\n")])])]),e("p",[t._v("Read changelog to learn more about version 👇")]),t._v(" "),e("h2",{attrs:{id:"_3-0-0-rc"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-0-0-rc"}},[t._v("#")]),t._v(" 3.0.0-rc")]),t._v(" "),e("ul",[e("li",[t._v("Moved "),e("a",{attrs:{href:"https://github.com/codeceptjs/helper",target:"_blank",rel:"noopener noreferrer"}},[t._v("Helper class into its own package"),e("OutboundLink")],1),t._v(" to simplify publishing standalone helpers.")]),t._v(" "),e("li",[t._v("Fixed typings for "),e("code",[t._v("I.say")]),t._v(" and "),e("code",[t._v("I.retry")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Updated documentation:\n"),e("ul",[e("li",[e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/blob/codeceptjs-v3.0/docs/quickstart.md#quickstart",target:"_blank",rel:"noopener noreferrer"}},[t._v("Quickstart"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/blob/codeceptjs-v3.0/docs/best.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Best Practices"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/blob/codeceptjs-v3.0/docs/custom-helpers.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Custom Helpers"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/blob/codeceptjs-v3.0/docs/typescript.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("TypeScript"),e("OutboundLink")],1)])])])]),t._v(" "),e("h2",{attrs:{id:"_3-0-0-beta-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-0-0-beta-4"}},[t._v("#")]),t._v(" 3.0.0-beta.4")]),t._v(" "),e("p",[t._v("🐛 Bug Fix:")]),t._v(" "),e("ul",[e("li",[t._v('PageObject was broken when using "this" inside a simple object.')]),t._v(" "),e("li",[t._v("The typings for all WebDriver methods work correctly.")]),t._v(" "),e("li",[t._v('The typings for "this.helper" and helper constructor work correctly, too.')])]),t._v(" "),e("p",[t._v("🧤 Internal:")]),t._v(" "),e("ul",[e("li",[t._v("Our TS Typings will be tested now! We strarted using "),e("a",{attrs:{href:"https://github.com/microsoft/dtslint",target:"_blank",rel:"noopener noreferrer"}},[t._v("dtslint"),e("OutboundLink")],1),t._v(" to check all typings and all rules for linter.\nExample:")])]),t._v(" "),e("div",{staticClass:"language-ts extra-class"},[e("pre",{pre:!0,attrs:{class:"language-ts"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" psp "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" wd"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabPageScrollPosition")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// $ExpectType Promise")]),t._v("\npsp"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("then")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n result "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n result"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("x "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// $ExpectType number")]),t._v("\n result"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("y "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// $ExpectType number")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("ul",[e("li",[t._v("And last: Reducing package size from 3.3Mb to 2.0Mb")])]),t._v(" "),e("h2",{attrs:{id:"_3-0-0-beta-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-0-0-beta-3"}},[t._v("#")]),t._v(" 3.0.0-beta-3")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("BREAKING")]),t._v(" Replaced bootstrap/teardown scripts to accept only functions or async functions. Async function with callback (with done parameter) should be replaced with async/await. "),e("a",{attrs:{href:"https://bit.ly/codecept3Up",target:"_blank",rel:"noopener noreferrer"}},[t._v("See our upgrde guide"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[t._v("Test artifacts introduced. Each test object has "),e("code",[t._v("artifacts")]),t._v(" property, to keep attachment files. For instance, a screenshot of a failed test is attached to a test as artifact.")]),t._v(" "),e("li",[t._v("Improved output for test execution\n"),e("ul",[e("li",[t._v("Changed colors for steps output, simplified")]),t._v(" "),e("li",[t._v("Added stack trace for test failures")]),t._v(" "),e("li",[t._v("Removed "),e("code",[t._v("Event emitted")]),t._v(" from log in "),e("code",[t._v("--verbose")]),t._v(" mode")]),t._v(" "),e("li",[t._v("List artifacts of a failed tests")])])])]),t._v(" "),e("p",[e("img",{attrs:{src:"https://user-images.githubusercontent.com/220264/82160052-397bf800-989b-11ea-81c0-8e58b3d33525.png",alt:""}})]),t._v(" "),e("ul",[e("li",[t._v("Steps & metasteps refactored by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)]),t._v(". Logs to arguments passed to page objects:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// TEST:")]),t._v("\nMyPage"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("hasFiles")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'first arg'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'second arg'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// OUTPUT:")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("MyPage")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" hasFile "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"First arg"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Second arg"')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" see file "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"codecept.js"')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" see file "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"codecept.po.json"')]),t._v("\n")])])]),e("ul",[e("li",[t._v("Introduced official "),e("a",{attrs:{href:"https://github.com/codeceptjs/typescript-boilerplate",target:"_blank",rel:"noopener noreferrer"}},[t._v("TypeScript boilerplate"),e("OutboundLink")],1),t._v(". Started by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)]),t._v(".")])]),t._v(" "),e("h2",{attrs:{id:"_3-0-0-beta"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_3-0-0-beta"}},[t._v("#")]),t._v(" 3.0.0-beta")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("NodeJS 12+ required")])]),t._v(" "),e("li",[e("strong",[t._v("BREAKING CHANGE:")]),t._v(" Syntax for tests has changed.")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Previous")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'title'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" loginPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Current")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'title'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" loginPage "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("p",[e("strong",[t._v("BREAKING CHANGE:")]),t._v(" [WebDriver][Protractor][Puppeteer][Playwright][Nightmare] "),e("code",[t._v("grab*")]),t._v(" functions unified:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("grab*From")]),t._v(" => "),e("strong",[t._v("returns single value")]),t._v(" from element or throws error when no matchng elements found")]),t._v(" "),e("li",[e("code",[t._v("grab*FromAll")]),t._v(" => returns array of values, or empty array when no matching elements")])])]),t._v(" "),e("li",[e("p",[t._v("Public API for workers introduced by "),e("strong",[e("a",{attrs:{href:"https://github.com/koushikmohan1996",target:"_blank",rel:"noopener noreferrer"}},[t._v("koushikmohan1996"),e("OutboundLink")],1)]),t._v(". "),e("a",{attrs:{href:"https://github.com/Codeception/CodeceptJS/blob/codeceptjs-v3.0/docs/parallel.md#custom-parallel-execution",target:"_blank",rel:"noopener noreferrer"}},[t._v("Customize parallel execution"),e("OutboundLink")],1),t._v(" with workers by building custom scripts.")])]),t._v(" "),e("li",[e("p",[e("strong",[t._v("[Playwright]")]),t._v(" Added "),e("code",[t._v("usePlaywrightTo")]),t._v(" method to access Playwright API in tests directly:")])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("usePlaywrightTo")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'do something special'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" page "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// use page or browser objects here")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Introduced "),e("code",[t._v("usePuppeteerTo")]),t._v(" method to access Puppeteer API:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("usePuppeteerTo")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'do something special'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" page"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" browser "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// use page or browser objects here")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Introduced "),e("code",[t._v("useWebDriverTo")]),t._v(" method to access webdriverio API:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("useWebDriverTo")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'do something special'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" browser "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// use browser object here")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("strong",[t._v("[Protractor]")]),t._v(" Introduced "),e("code",[t._v("useProtractorTo")]),t._v(" method to access protractor API")]),t._v(" "),e("li",[e("code",[t._v("tryTo")]),t._v(" plugin introduced. Allows conditional action execution:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" isSeen "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("tryTo")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Some text'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// we are not sure if cookie bar is displayed, but if so - accept cookies")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("tryTo")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Accept'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.cookies'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("strong",[t._v("Possible breaking change")]),t._v(" In semantic locators "),e("code",[t._v("[")]),t._v(" char indicates CSS selector.")])]),t._v(" "),e("h2",{attrs:{id:"_2-6-11"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-6-11"}},[t._v("#")]),t._v(" 2.6.11")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Playwright 1.4 compatibility")]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Added "),e("code",[t._v("ignoreHTTPSErrors")]),t._v(" config option (default: false). See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2566",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2566"),e("OutboundLink")],1),t._v(" by gurjeetbains")]),t._v(" "),e("li",[t._v("Added French translation by "),e("strong",[e("a",{attrs:{href:"https://github.com/vimar",target:"_blank",rel:"noopener noreferrer"}},[t._v("vimar"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Updated "),e("code",[t._v("dragSlider")]),t._v(" to work in WebDriver W3C protocol. Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2557",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2557"),e("OutboundLink")],1),t._v(" by suniljaiswal01")])]),t._v(" "),e("h2",{attrs:{id:"_2-6-10"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-6-10"}},[t._v("#")]),t._v(" 2.6.10")]),t._v(" "),e("ul",[e("li",[t._v("Fixed saving options for suite via "),e("code",[t._v("Feature('title', {key: value})")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Diokuz",target:"_blank",rel:"noopener noreferrer"}},[t._v("Diokuz"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2553",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2553"),e("OutboundLink")],1),t._v(" and "),e("a",{attrs:{href:"https://codecept.io/advanced/#dynamic-configuration",target:"_blank",rel:"noopener noreferrer"}},[t._v("Docs"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_2-6-9"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-6-9"}},[t._v("#")]),t._v(" 2.6.9")]),t._v(" "),e("ul",[e("li",[t._v("[Puppeteer][Playwright] SessionStorage is now cleared in after hook. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2524",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2524"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("When helper load failed the error stack is now logged by "),e("strong",[e("a",{attrs:{href:"https://github.com/SkReD",target:"_blank",rel:"noopener noreferrer"}},[t._v("SkReD"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2541",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2541"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Small documentation fixes.")])]),t._v(" "),e("h2",{attrs:{id:"_2-6-8"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-6-8"}},[t._v("#")]),t._v(" 2.6.8")]),t._v(" "),e("ul",[e("li",[t._v("[WebDriver][Protractor][Playwright][Puppeteer][Nightmare] "),e("code",[t._v("saveElementScreenshot")]),t._v(" method added to make screenshot of an element. By "),e("strong",[e("a",{attrs:{href:"https://github.com/suniljaiswal01",target:"_blank",rel:"noopener noreferrer"}},[t._v("suniljaiswal01"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[Playwright][Puppeteer] Added "),e("code",[t._v("type")]),t._v(" method to type a text using keyboard with an optional delay.")]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Added optional "),e("code",[t._v("delay")]),t._v(" argument to "),e("code",[t._v("type")]),t._v(" method to slow down typing.")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed "),e("code",[t._v("amOnPage")]),t._v(" freeze when "),e("code",[t._v("getPageTimeout")]),t._v(' is 0"; set 30 sec as default timeout by '),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("Fixed printing step with null argument in custom helper by "),e("strong",[e("a",{attrs:{href:"https://github.com/sjana-aj",target:"_blank",rel:"noopener noreferrer"}},[t._v("sjana-aj"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2494",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2494"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Fix missing screenshot on failure when REST helper is in use "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2513",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2513"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Improve error logging in the "),e("code",[t._v("screenshotOnFail")]),t._v(" plugin "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2512",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2512"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/pablopaul",target:"_blank",rel:"noopener noreferrer"}},[t._v("pablopaul"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_2-6-7"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-6-7"}},[t._v("#")]),t._v(" 2.6.7")]),t._v(" "),e("ul",[e("li",[t._v("Add REST helper into "),e("code",[t._v("standardActingHelpers")]),t._v(" array "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2474",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2474"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Add missing "),e("code",[t._v("--invert")]),t._v(" option for "),e("code",[t._v("run-workers")]),t._v(" command "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2504",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2504"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/pablopaul",target:"_blank",rel:"noopener noreferrer"}},[t._v("pablopaul"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Introduce "),e("code",[t._v("forceRightClick")]),t._v(" method "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2485",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2485"),e("OutboundLink")],1),t._v(" bylsuniljaiswal01")]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Fix "),e("code",[t._v("setCookie")]),t._v(" method "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2491",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2491"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/bmbarker90",target:"_blank",rel:"noopener noreferrer"}},[t._v("bmbarker90"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[TypeScript]")]),t._v(" Update compilerOptions.target to es2017 "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2483",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2483"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/shanplourde",target:"_blank",rel:"noopener noreferrer"}},[t._v("shanplourde"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Mocha]")]),t._v(" Honor reporter configuration "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2465",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2465"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/trinhpham",target:"_blank",rel:"noopener noreferrer"}},[t._v("trinhpham"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_2-6-6"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-6-6"}},[t._v("#")]),t._v(" 2.6.6")]),t._v(" "),e("ul",[e("li",[t._v("Puppeteer 4.0 support. Important: MockRequest helper won't work with Puppeter > 3.3")]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("xFeature")]),t._v(" and "),e("code",[t._v("Feature.skip")]),t._v(" to skip all tests in a suite. By "),e("strong",[e("a",{attrs:{href:"https://github.com/Georgegriff",target:"_blank",rel:"noopener noreferrer"}},[t._v("Georgegriff"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Appium]")]),t._v(" Fixed "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2428",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2428"),e("OutboundLink")],1),t._v(" Android native locator support by "),e("strong",[e("a",{attrs:{href:"https://github.com/idxn",target:"_blank",rel:"noopener noreferrer"}},[t._v("idxn"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Fixed "),e("code",[t._v("waitNumberOfVisibleElements")]),t._v(" to actually filter visible elements. By "),e("strong",[e("a",{attrs:{href:"https://github.com/ilangv",target:"_blank",rel:"noopener noreferrer"}},[t._v("ilangv"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed handling error which is not an Error object. Fixes "),e("code",[t._v("cannot read property indexOf of undefined")]),t._v(" error. Fix "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2436",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2436"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Georgegriff",target:"_blank",rel:"noopener noreferrer"}},[t._v("Georgegriff"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Print error on page crash by "),e("strong",[e("a",{attrs:{href:"https://github.com/Georgegriff",target:"_blank",rel:"noopener noreferrer"}},[t._v("Georgegriff"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_2-6-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-6-5"}},[t._v("#")]),t._v(" 2.6.5")]),t._v(" "),e("ul",[e("li",[t._v("Added "),e("code",[t._v("test.skipped")]),t._v(" event to run-workers, fixing allure reports with skipped tests in workers "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2391",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2391"),e("OutboundLink")],1),t._v(". Fix "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2387",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2387"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/koushikmohan1996",target:"_blank",rel:"noopener noreferrer"}},[t._v("koushikmohan1996"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Fixed calling "),e("code",[t._v("waitFor*")]),t._v(" methods with custom locators "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2314",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2314"),e("OutboundLink")],1),t._v(". Fix "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2389",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2389"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Georgegriff",target:"_blank",rel:"noopener noreferrer"}},[t._v("Georgegriff"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_2-6-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-6-4"}},[t._v("#")]),t._v(" 2.6.4")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Playwright]")]),t._v(" "),e("strong",[t._v("Playwright 1.0 support")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Georgegriff",target:"_blank",rel:"noopener noreferrer"}},[t._v("Georgegriff"),e("OutboundLink")],1)]),t._v(".")])]),t._v(" "),e("h2",{attrs:{id:"_2-6-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-6-3"}},[t._v("#")]),t._v(" 2.6.3")]),t._v(" "),e("ul",[e("li",[t._v("[stepByStepReport plugin] Fixed when using plugin with BeforeSuite. Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2337",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2337"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[allure plugin] Fixed reporting of tests skipped by failure in before hook. Refer to "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2349",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2349"),e("OutboundLink")],1),t._v(" & "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2354",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2354"),e("OutboundLink")],1),t._v(". Fix by "),e("strong",[e("a",{attrs:{href:"https://github.com/koushikmohan1996",target:"_blank",rel:"noopener noreferrer"}},[t._v("koushikmohan1996"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_2-6-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-6-2"}},[t._v("#")]),t._v(" 2.6.2")]),t._v(" "),e("ul",[e("li",[t._v("[WebDriver][Puppeteer] Added "),e("code",[t._v("forceClick")]),t._v(" method to emulate click event instead of using native events.")]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Updated to 0.14")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Updated to Puppeteer v3.0")]),t._v(" "),e("li",[e("strong",[t._v("[wdio]")]),t._v(" Fixed undefined output directory for wdio plugns. Fix By "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Introduced "),e("code",[t._v("handleDownloads")]),t._v(" method to download file. Please note, this method has slightly different API than the same one in Puppeteer.")]),t._v(" "),e("li",[e("strong",[t._v("[allure]")]),t._v(" Fixed undefined output directory for allure plugin on using custom runner. Fix by "),e("strong",[e("a",{attrs:{href:"https://github.com/charliepradeep",target:"_blank",rel:"noopener noreferrer"}},[t._v("charliepradeep"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Fixed "),e("code",[t._v("waitForEnabled")]),t._v(" fix for webdriver 6. Fix by "),e("strong",[e("a",{attrs:{href:"https://github.com/dsharapkou",target:"_blank",rel:"noopener noreferrer"}},[t._v("dsharapkou"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Workers: Fixed negative failure result if use scenario with the same names. Fix by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[MockRequest]")]),t._v(" Updated documentation to match new helper version")]),t._v(" "),e("li",[t._v("Fixed: skipped tests are not reported if a suite failed in "),e("code",[t._v("before")]),t._v(". Refer "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2349",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2349"),e("OutboundLink")],1),t._v(" & "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2354",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2354"),e("OutboundLink")],1),t._v(". Fix by "),e("strong",[e("a",{attrs:{href:"https://github.com/koushikmohan1996",target:"_blank",rel:"noopener noreferrer"}},[t._v("koushikmohan1996"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_2-6-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-6-1"}},[t._v("#")]),t._v(" 2.6.1")]),t._v(" "),e("ul",[e("li",[t._v("[screenshotOnFail plugin] Fixed saving screenshot of active session.")]),t._v(" "),e("li",[t._v("[screenshotOnFail plugin] Fix issue "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2301",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2301"),e("OutboundLink")],1),t._v(" when having the flag "),e("code",[t._v("uniqueScreenshotNames")]),t._v("=true results in "),e("code",[t._v("undefined")]),t._v(" in screenshot file name by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Fixed "),e("code",[t._v("waitForElement")]),t._v(" not applying the optional second argument to override the default timeout in webdriverio 6. Fix by "),e("strong",[e("a",{attrs:{href:"https://github.com/Mooksc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mooksc"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Updated "),e("code",[t._v("waitUntil")]),t._v(" method which is used by all of the wait* functions. This updates the "),e("code",[t._v("waitForElement")]),t._v(" by the same convention used to update "),e("code",[t._v("waitForVisible")]),t._v(" and "),e("code",[t._v("waitInUrl")]),t._v(" to be compatible with both WebDriverIO v5 & v6. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2313",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2313"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Mooksc",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mooksc"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_2-6-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-6-0"}},[t._v("#")]),t._v(" 2.6.0")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Playwright] Updated to Playwright 0.12")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Georgegriff",target:"_blank",rel:"noopener noreferrer"}},[t._v("Georgegriff"),e("OutboundLink")],1)]),t._v(".")])]),t._v(" "),e("p",[t._v("Upgrade playwright to ^0.12:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("npm i playwright@^0.12 --save\n")])])]),e("p",[e("a",{attrs:{href:"https://github.com/microsoft/playwright/releases/tag/v0.12.0",target:"_blank",rel:"noopener noreferrer"}},[t._v("Notable changes"),e("OutboundLink")],1),t._v(":")]),t._v(" "),e("ul",[e("li",[t._v("Fixed opening two browsers on start")]),t._v(" "),e("li",[e("code",[t._v("executeScript")]),t._v(" - passed function now accepts only one argument. Pass in objects or arrays if you need multtple arguments:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Old style, does not work anymore:")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("executeScript")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("x"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" x "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" y"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" x"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// New style, passing an object:")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("executeScript")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("x"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" x "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v(" y"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("x"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" y"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("code",[t._v("click")]),t._v(" - automatically waits for element to become clickable (visible, not animated) and waits for navigation.")]),t._v(" "),e("li",[e("code",[t._v("clickLink")]),t._v(" - deprecated")]),t._v(" "),e("li",[e("code",[t._v("waitForClickable")]),t._v(" - deprecated")]),t._v(" "),e("li",[e("code",[t._v("forceClick")]),t._v(" - added")]),t._v(" "),e("li",[t._v("Added support for custom locators. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2277",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2277"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Introduced "),e("RouterLink",{attrs:{to:"/playwright/#device-emulation"}},[t._v("device emulation")]),t._v(":\n"),e("ul",[e("li",[t._v("globally via "),e("code",[t._v("emulate")]),t._v(" config option")]),t._v(" "),e("li",[t._v("per session")])])],1)]),t._v(" "),e("p",[e("strong",[t._v("[WebDriver] Updated to webdriverio v6")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("p",[t._v("Read "),e("a",{attrs:{href:"https://webdriver.io/blog/2020/03/26/webdriverio-v6-released.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("release notes"),e("OutboundLink")],1),t._v(", then\nupgrade webdriverio to ^6.0:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("npm i webdriverio@^6.0 --save\n")])])]),e("p",[e("em",[t._v("(webdriverio v5 support is deprecated and will be removed in CodeceptJS 3.0)")]),t._v(" "),e("strong",[t._v("[WebDriver]")]),t._v(" Introduced "),e("a",{attrs:{href:"/shadow"}},[t._v("Shadow DOM support")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/gkushang",target:"_blank",rel:"noopener noreferrer"}},[t._v("gkushang"),e("OutboundLink")],1)])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("shadow")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'my-app'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'recipe-hello'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'button'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("strong",[t._v("Fixed parallel execution of "),e("code",[t._v("run-workers")]),t._v(" for Gherkin")]),t._v(" scenarios by "),e("strong",[e("a",{attrs:{href:"https://github.com/koushikmohan1996",target:"_blank",rel:"noopener noreferrer"}},[t._v("koushikmohan1996"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[MockRequest]")]),t._v(" Updated and "),e("strong",[t._v("moved to "),e("a",{attrs:{href:"https://github.com/codeceptjs/mock-request",target:"_blank",rel:"noopener noreferrer"}},[t._v("standalone package"),e("OutboundLink")],1)]),t._v(":\n"),e("ul",[e("li",[t._v("full support for record/replay mode for Puppeteer")]),t._v(" "),e("li",[t._v("added "),e("code",[t._v("mockServer")]),t._v(" method to use flexible PollyJS API to define mocks")]),t._v(" "),e("li",[t._v("fixed stale browser screen in record mode.")])])]),t._v(" "),e("li",[e("strong",[t._v("[Playwright]")]),t._v(" Added support on for "),e("code",[t._v("screenshotOnFail")]),t._v(" plugin by "),e("strong",[e("a",{attrs:{href:"https://github.com/amonkc",target:"_blank",rel:"noopener noreferrer"}},[t._v("amonkc"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Gherkin improvement: setting different tags per examples. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2208",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2208"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/acuper",target:"_blank",rel:"noopener noreferrer"}},[t._v("acuper"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[TestCafe]")]),t._v(" Updated "),e("code",[t._v("click")]),t._v(" to take first visible element. Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2226",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2226"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/theTainted",target:"_blank",rel:"noopener noreferrer"}},[t._v("theTainted"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[Puppeteer][WebDriver] Updated "),e("code",[t._v("waitForClickable")]),t._v(" method to check for element overlapping. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2261",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2261"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PiQx",target:"_blank",rel:"noopener noreferrer"}},[t._v("PiQx"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Dropped "),e("code",[t._v("puppeteer-firefox")]),t._v(" support, as Puppeteer supports Firefox natively.")]),t._v(" "),e("li",[e("strong",[t._v("[REST]")]),t._v(" Rrespect Content-Type header. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2262",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2262"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/pmarshall-legacy",target:"_blank",rel:"noopener noreferrer"}},[t._v("pmarshall-legacy"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[allure plugin] Fixes BeforeSuite failures in allure reports. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2248",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2248"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Georgegriff",target:"_blank",rel:"noopener noreferrer"}},[t._v("Georgegriff"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[WebDriver][Puppeteer][Playwright] A screenshot of for an active session is saved in multi-session mode. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2253",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2253"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/ChexWarrior",target:"_blank",rel:"noopener noreferrer"}},[t._v("ChexWarrior"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed "),e("code",[t._v("--profile")]),t._v(" option by "),e("strong",[e("a",{attrs:{href:"https://github.com/pablopaul",target:"_blank",rel:"noopener noreferrer"}},[t._v("pablopaul"),e("OutboundLink")],1)]),t._v(". Profile value to be passed into "),e("code",[t._v("run-multiple")]),t._v(" and "),e("code",[t._v("run-workers")]),t._v(":")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("npx codecept run-workers 2 --profile firefox\n")])])]),e("p",[t._v("Value is available at "),e("code",[t._v("process.env.profile")]),t._v(" (previously "),e("code",[t._v("process.profile")]),t._v("). See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2302",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2302"),e("OutboundLink")],1),t._v(". Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1968",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1968"),e("OutboundLink")],1),t._v(" "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1315",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1315"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"/plugins#commentstep"}},[t._v("commentStep Plugin introduced")]),t._v(". Allows to annotate logical parts of a test:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[t._v("__"),e("span",{pre:!0,attrs:{class:"token template-string"}},[e("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("Given")]),e("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/profile'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n__"),e("span",{pre:!0,attrs:{class:"token template-string"}},[e("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("When")]),e("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Logout'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n__"),e("span",{pre:!0,attrs:{class:"token template-string"}},[e("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("Then")]),e("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'You are logged out'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h2",{attrs:{id:"_2-5-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-5-0"}},[t._v("#")]),t._v(" 2.5.0")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Experimental: "),e("a",{attrs:{href:"/playwright"}},[t._v("Playwright")]),t._v(" helper introduced")]),t._v(".")])]),t._v(" "),e("blockquote",[e("p",[e("a",{attrs:{href:"https://github.com/microsoft/playwright/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Playwright"),e("OutboundLink")],1),t._v(" is an alternative to Puppeteer which works very similarly to it but adds cross-browser support with Firefox and Webkit. Until v1.0 Playwright API is not stable but we introduce it to CodeceptJS so you could try it.")])]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed basic auth support when running in multiple sessions. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2178",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2178"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/ian-bartholomew",target:"_blank",rel:"noopener noreferrer"}},[t._v("ian-bartholomew"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed "),e("code",[t._v("waitForText")]),t._v(" when there is no "),e("code",[t._v("body")]),t._v(" element on page (redirect). See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2181",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2181"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[Selenoid plugin] Fixed overriding current capabilities by adding deepMerge. Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2183",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2183"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/koushikmohan1996",target:"_blank",rel:"noopener noreferrer"}},[t._v("koushikmohan1996"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added types for "),e("code",[t._v("Scenario.todo")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added types for Mocha by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)]),t._v(". Fixed typing conflicts with Jest")]),t._v(" "),e("li",[e("strong",[t._v("[FileSystem]")]),t._v(" Added methods by "),e("strong",[e("a",{attrs:{href:"https://github.com/nitschSB",target:"_blank",rel:"noopener noreferrer"}},[t._v("nitschSB"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[e("code",[t._v("waitForFile")])]),t._v(" "),e("li",[e("code",[t._v("seeFileContentsEqualReferenceFile")])])])]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("--colors")]),t._v(" option to "),e("code",[t._v("run")]),t._v(" and "),e("code",[t._v("run-multiple")]),t._v(" so you force colored output in dockerized environment. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2189",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2189"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Added "),e("code",[t._v("type")]),t._v(" command to enter value without focusing on a field. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2198",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2198"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/xMutaGenx",target:"_blank",rel:"noopener noreferrer"}},[t._v("xMutaGenx"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed "),e("code",[t._v("codeceptjs gt")]),t._v(" command to respect config pattern for tests. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2200",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2200"),e("OutboundLink")],1),t._v(" and "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2204",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2204"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/matheo",target:"_blank",rel:"noopener noreferrer"}},[t._v("matheo"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_2-4-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-4-3"}},[t._v("#")]),t._v(" 2.4.3")]),t._v(" "),e("ul",[e("li",[t._v("Hotfix for interactive pause")])]),t._v(" "),e("h2",{attrs:{id:"_2-4-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-4-2"}},[t._v("#")]),t._v(" 2.4.2")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Interactive pause improvements")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/koushikmohan1996",target:"_blank",rel:"noopener noreferrer"}},[t._v("koushikmohan1996"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[t._v("allows using in page objects and variables: "),e("code",[t._v("pause({ loginPage, a })")])]),t._v(" "),e("li",[t._v("enables custom commands inside pause with "),e("code",[t._v("=>")]),t._v(" prefix: "),e("code",[t._v("=> loginPage.open()")])])])]),t._v(" "),e("li",[e("a",{attrs:{href:"/plugins#selenoid"}},[t._v("Selenoid plugin")]),t._v(" added by by "),e("strong",[e("a",{attrs:{href:"https://github.com/koushikmohan1996",target:"_blank",rel:"noopener noreferrer"}},[t._v("koushikmohan1996"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[t._v("uses Selenoid to launch browsers inside Docker containers")]),t._v(" "),e("li",[t._v("automatically "),e("strong",[t._v("records videos")]),t._v(" and attaches them to allure reports")]),t._v(" "),e("li",[t._v("can delete videos for successful tests")]),t._v(" "),e("li",[t._v("can automatically pull in and start Selenoid containers")]),t._v(" "),e("li",[t._v("works with WebDriver helper")])])]),t._v(" "),e("li",[t._v("Avoid failiure report on successful retry in worker by "),e("strong",[e("a",{attrs:{href:"https://github.com/koushikmohan1996",target:"_blank",rel:"noopener noreferrer"}},[t._v("koushikmohan1996"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added translation ability to Scenario, Feature and other context methods by "),e("strong",[e("a",{attrs:{href:"https://github.com/koushikmohan1996",target:"_blank",rel:"noopener noreferrer"}},[t._v("koushikmohan1996"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[t._v("📢 Please help us translate context methods to your language! See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/blob/master/translations/it-IT.js#L3",target:"_blank",rel:"noopener noreferrer"}},[t._v("italian translation"),e("OutboundLink")],1),t._v(" as an example and send "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/master/translations",target:"_blank",rel:"noopener noreferrer"}},[t._v("patches to vocabularies"),e("OutboundLink")],1),t._v(".")])])]),t._v(" "),e("li",[t._v("allurePlugin: Added "),e("code",[t._v("say")]),t._v(" comments to allure reports by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("Fixed no custom output folder created when executed with run-worker. Fix by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed error description for context element not found. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2065",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2065"),e("OutboundLink")],1),t._v(". Fix by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Fixed "),e("code",[t._v("waitForClickable")]),t._v(" to wait for exact number of seconds by "),e("strong",[e("a",{attrs:{href:"https://github.com/mirao",target:"_blank",rel:"noopener noreferrer"}},[t._v("mirao"),e("OutboundLink")],1)]),t._v(". Resolves "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2166",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2166"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Fixed setting "),e("code",[t._v("compilerOptions")]),t._v(" in "),e("code",[t._v("jsconfig.json")]),t._v(" file on init by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Filesystem]")]),t._v(" Added method by "),e("strong",[e("a",{attrs:{href:"https://github.com/nitschSB",target:"_blank",rel:"noopener noreferrer"}},[t._v("nitschSB"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[e("code",[t._v("seeFileContentsEqualReferenceFile")])]),t._v(" "),e("li",[e("code",[t._v("waitForFile")])])])])]),t._v(" "),e("h2",{attrs:{id:"_2-4-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-4-1"}},[t._v("#")]),t._v(" 2.4.1")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Hotfix]")]),t._v(" - Add missing lib that prevents codeceptjs from initializing.")])]),t._v(" "),e("h2",{attrs:{id:"_2-4-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-4-0"}},[t._v("#")]),t._v(" 2.4.0")]),t._v(" "),e("ul",[e("li",[t._v("Improved setup wizard with "),e("code",[t._v("npx codecept init")]),t._v(":\n"),e("ul",[e("li",[e("strong",[t._v("enabled "),e("RouterLink",{attrs:{to:"/plugins/#retryfailedstep"}},[t._v("retryFailedStep")]),t._v(" plugin for new setups")],1),t._v(".")]),t._v(" "),e("li",[t._v("enabled "),e("RouterLink",{attrs:{to:"/configuration/#common-configuration-patterns"}},[t._v("@codeceptjs/configure")]),t._v(" to toggle headless/window mode via env variable")],1),t._v(" "),e("li",[t._v("creates a new test on init")]),t._v(" "),e("li",[t._v('removed question on "steps file", create it by default.')])])]),t._v(" "),e("li",[t._v("Added "),e("RouterLink",{attrs:{to:"/plugins/#pauseonfail"}},[t._v("pauseOnFail plugin")]),t._v(". "),e("em",[t._v('Sponsored by Paul Vincent Beigang and his book "'),e("a",{attrs:{href:"https://leanpub.com/codeceptjs/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Practical End 2 End Testing with CodeceptJS"),e("OutboundLink")],1),t._v('"')]),t._v(".")],1),t._v(" "),e("li",[t._v("Added "),e("RouterLink",{attrs:{to:"/commands/#run-rerun"}},[e("code",[t._v("run-rerun")]),t._v(" command")]),t._v(" to run tests multiple times to detect and fix flaky tests. By "),e("strong",[e("a",{attrs:{href:"https://github.com/Ilrilan",target:"_blank",rel:"noopener noreferrer"}},[t._v("Ilrilan"),e("OutboundLink")],1)]),t._v(" and "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)]),t._v(".")],1),t._v(" "),e("li",[t._v("Added "),e("a",{attrs:{href:"/basics#todotest"}},[e("code",[t._v("Scenario.todo()")]),t._v(" to declare tests as pending")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2100",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2100"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added support for absolute path for "),e("code",[t._v("output")]),t._v(" dir. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2049",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2049"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/elukoyanov",target:"_blank",rel:"noopener noreferrer"}},[t._v("elukoyanov"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed error in "),e("code",[t._v("npx codecept init")]),t._v(" caused by calling "),e("code",[t._v("console.print")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2071",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2071"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Atinux",target:"_blank",rel:"noopener noreferrer"}},[t._v("Atinux"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Filesystem]")]),t._v(" Methods added by "),e("strong",[e("a",{attrs:{href:"https://github.com/aefluke",target:"_blank",rel:"noopener noreferrer"}},[t._v("aefluke"),e("OutboundLink")],1)]),t._v(":\n"),e("ul",[e("li",[e("code",[t._v("seeFileNameMatching")])]),t._v(" "),e("li",[e("code",[t._v("grabFileNames")])])])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed grabbing attributes with hyphen by "),e("strong",[e("a",{attrs:{href:"https://github.com/Holorium",target:"_blank",rel:"noopener noreferrer"}},[t._v("Holorium"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[TestCafe]")]),t._v(" Fixed "),e("code",[t._v("grabAttributeFrom")]),t._v(" method by "),e("strong",[e("a",{attrs:{href:"https://github.com/elukoyanov",target:"_blank",rel:"noopener noreferrer"}},[t._v("elukoyanov"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[MockRequest]")]),t._v(" Added support for "),e("a",{attrs:{href:"https://netflix.github.io/pollyjs/#/configuration?id=configuration",target:"_blank",rel:"noopener noreferrer"}},[t._v("Polly config options"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/ecrmnn",target:"_blank",rel:"noopener noreferrer"}},[t._v("ecrmnn"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[TestCafe]")]),t._v(" Fixes exiting with zero code on failure. Fixed "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2090",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2090"),e("OutboundLink")],1),t._v(" with "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2106",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2106"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/koushikmohan1996",target:"_blank",rel:"noopener noreferrer"}},[t._v("koushikmohan1996"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[WebDriver][Puppeteer] Added basicAuth support via config. Example: "),e("code",[t._v("basicAuth: {username: 'username', password: 'password'}")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1962",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1962"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[WebDriver][Appium] Added "),e("code",[t._v("scrollIntoView")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/pablopaul",target:"_blank",rel:"noopener noreferrer"}},[t._v("pablopaul"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2118",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2118"),e("OutboundLink")],1),t._v(": No error stack trace for syntax error by "),e("strong",[e("a",{attrs:{href:"https://github.com/senthillkumar",target:"_blank",rel:"noopener noreferrer"}},[t._v("senthillkumar"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("parse()")]),t._v(" method to data table inside Cucumber tests. Use it to obtain rows and hashes for test data. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2082",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2082"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Sraime",target:"_blank",rel:"noopener noreferrer"}},[t._v("Sraime"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_2-3-6"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-6"}},[t._v("#")]),t._v(" 2.3.6")]),t._v(" "),e("ul",[e("li",[t._v("Create better Typescript definition file through JSDoc. By "),e("strong",[e("a",{attrs:{href:"https://github.com/lemnis",target:"_blank",rel:"noopener noreferrer"}},[t._v("lemnis"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("run-workers")]),t._v(" now can use glob pattern. By "),e("strong",[e("a",{attrs:{href:"https://github.com/Ilrilan",target:"_blank",rel:"noopener noreferrer"}},[t._v("Ilrilan"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Example:")]),t._v("\nexports"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("tests")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'{./workers/base_test.workers.js,./workers/test_grep.workers.js}'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Added new command "),e("code",[t._v("npx codeceptjs info")]),t._v(" which print information about your environment and CodeceptJS configs. By "),e("strong",[e("a",{attrs:{href:"https://github.com/jamesgeorge007",target:"_blank",rel:"noopener noreferrer"}},[t._v("jamesgeorge007"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed some typos in documantation. By "),e("strong",[e("a",{attrs:{href:"https://github.com/pablopaul",target:"_blank",rel:"noopener noreferrer"}},[t._v("pablopaul"),e("OutboundLink")],1)]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://github.com/atomicpages",target:"_blank",rel:"noopener noreferrer"}},[t._v("atomicpages"),e("OutboundLink")],1)]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://github.com/EricTendian",target:"_blank",rel:"noopener noreferrer"}},[t._v("EricTendian"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added PULL_REQUEST template.")]),t._v(" "),e("li",[t._v("[Puppeteer][WebDriver] Added "),e("code",[t._v("waitForClickable")]),t._v(" for waiting clickable element on page.")]),t._v(" "),e("li",[e("strong",[t._v("[TestCafe]")]),t._v(" Added support for remote connection. By "),e("strong",[e("a",{attrs:{href:"https://github.com/jvdieten",target:"_blank",rel:"noopener noreferrer"}},[t._v("jvdieten"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed "),e("code",[t._v("waitForText")]),t._v(" XPath context now works correctly. By "),e("strong",[e("a",{attrs:{href:"https://github.com/Heavik",target:"_blank",rel:"noopener noreferrer"}},[t._v("Heavik"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[TestCafe]")]),t._v(" Fixed "),e("code",[t._v("clearField")]),t._v(" clear field now awaits TestCafe's promise. By "),e("strong",[e("a",{attrs:{href:"https://github.com/orihomie",target:"_blank",rel:"noopener noreferrer"}},[t._v("orihomie"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed fails when executing localStorage on services pages. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2026",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2026"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Fixed empty tags in test name. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/2038",target:"_blank",rel:"noopener noreferrer"}},[t._v("#2038"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_2-3-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-5"}},[t._v("#")]),t._v(" 2.3.5")]),t._v(" "),e("ul",[e("li",[t._v('Set "parse-function" dependency to "5.2.11" to avoid further installation errors.')])]),t._v(" "),e("h2",{attrs:{id:"_2-3-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-4"}},[t._v("#")]),t._v(" 2.3.4")]),t._v(" "),e("ul",[e("li",[t._v("Fixed installation error \"Cannot find module '@babel/runtime/helpers/interopRequireDefault'\". The issue came from "),e("code",[t._v("parse-function")]),t._v(" package. Fixed by "),e("strong",[e("a",{attrs:{href:"https://github.com/pablopaul",target:"_blank",rel:"noopener noreferrer"}},[t._v("pablopaul"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed switching to iframe without an ID by "),e("strong",[e("a",{attrs:{href:"https://github.com/johnyb",target:"_blank",rel:"noopener noreferrer"}},[t._v("johnyb"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1974",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1974"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("--profile")]),t._v(" option to "),e("code",[t._v("run-workers")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/orihomie",target:"_blank",rel:"noopener noreferrer"}},[t._v("orihomie"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added a tag definition to "),e("code",[t._v("FeatureConfig")]),t._v(" and "),e("code",[t._v("ScenarioConfig")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/sseliverstov",target:"_blank",rel:"noopener noreferrer"}},[t._v("sseliverstov"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_2-3-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-3"}},[t._v("#")]),t._v(" 2.3.3")]),t._v(" "),e("ul",[e("li",[e("strong",[e("a",{attrs:{href:"#customlocator"}},[t._v("customLocator plugin")]),t._v(" introduced")]),t._v(". Adds a locator strategy for special test attributes on elements.")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// when data-test-id is a special test attribute")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// enable and configure plugin to replace this")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("css")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'[data-test-id=register_button]'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// with this")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'$register_button'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[t._v("[Puppeteer][WebDriver] "),e("code",[t._v("pressKey")]),t._v(" improvements by "),e("strong",[e("a",{attrs:{href:"https://github.com/martomo",target:"_blank",rel:"noopener noreferrer"}},[t._v("martomo"),e("OutboundLink")],1)]),t._v(":\nChanged pressKey method to resolve issues and extend functionality.\n"),e("ul",[e("li",[t._v("Did not properly recognize 'Meta' (or 'Command') as modifier key.")]),t._v(" "),e("li",[t._v("Right modifier keys did not work in WebDriver using JsonWireProtocol.")]),t._v(" "),e("li",[t._v("'Shift' + 'key' combination would not reflect actual keyboard behavior.")]),t._v(" "),e("li",[t._v("Respect sequence with multiple modifier keys passed to pressKey.")]),t._v(" "),e("li",[t._v("Added support to automatic change operation modifier key based on operating system.")])])]),t._v(" "),e("li",[t._v("[Puppeteer][WebDriver] Added "),e("code",[t._v("pressKeyUp")]),t._v(" and "),e("code",[t._v("pressKeyDown")]),t._v(" to press and release modifier keys like "),e("code",[t._v("Control")]),t._v(" or "),e("code",[t._v("Shift")]),t._v(". By "),e("strong",[e("a",{attrs:{href:"https://github.com/martomo",target:"_blank",rel:"noopener noreferrer"}},[t._v("martomo"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("[Puppeteer][WebDriver] Added "),e("code",[t._v("grabElementBoundingRect")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed speed degradation introduced in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1306",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1306"),e("OutboundLink")],1),t._v(" with accessibility locators support. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1953",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1953"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("Config.addHook")]),t._v(" to add a function that will update configuration on load.")]),t._v(" "),e("li",[t._v("Started "),e("a",{attrs:{href:"https://github.com/codeceptjs/configure",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("@codeceptjs/configure")]),e("OutboundLink")],1),t._v(" package with a collection of common configuration patterns.")]),t._v(" "),e("li",[e("strong",[t._v("[TestCafe]")]),t._v(" port's management removed (left on TestCafe itself) by "),e("strong",[e("a",{attrs:{href:"https://github.com/orihomie",target:"_blank",rel:"noopener noreferrer"}},[t._v("orihomie"),e("OutboundLink")],1)]),t._v(". Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1934",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1934"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[REST]")]),t._v(" Headers are no more declared as singleton variable. Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1959",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1959"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Updated Docker image to include run tests in workers with "),e("code",[t._v("NUMBER_OF_WORKERS")]),t._v(" env variable. By "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(".")])]),t._v(" "),e("h2",{attrs:{id:"_2-3-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-2"}},[t._v("#")]),t._v(" 2.3.2")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed Puppeteer 1.20 support by "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed "),e("code",[t._v("run-workers")]),t._v(" to run with complex configs. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1887",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1887"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/nitschSB",target:"_blank",rel:"noopener noreferrer"}},[t._v("nitschSB"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("--suites")]),t._v(" option to "),e("code",[t._v("run-workers")]),t._v(" to split suites by workers (tests of the same suite goes to teh same worker). Thanks "),e("strong",[e("a",{attrs:{href:"https://github.com/nitschSB",target:"_blank",rel:"noopener noreferrer"}},[t._v("nitschSB"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("Added a guide on "),e("a",{attrs:{href:"https://codecept.io/email",target:"_blank",rel:"noopener noreferrer"}},[t._v("Email Testing"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[retryFailedStepPlugin]")]),t._v(" Improved to ignore wait* steps and others. Also added option to ignore this plugin per test bases. See "),e("a",{attrs:{href:"https://codecept.io/plugins#retryfailedstep",target:"_blank",rel:"noopener noreferrer"}},[t._v("updated documentation"),e("OutboundLink")],1),t._v(". By "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed using PageObjects as classes by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1896",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1896"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Fixed opening more than one tab. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1875",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1875"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/jplegoff",target:"_blank",rel:"noopener noreferrer"}},[t._v("jplegoff"),e("OutboundLink")],1)]),t._v(". Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1874",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1874"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Fixed "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1891",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1891"),e("OutboundLink")],1),t._v(" when "),e("code",[t._v("I.retry()")]),t._v(" affected retries of next steps. By "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_2-3-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-1"}},[t._v("#")]),t._v(" 2.3.1")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[MockRequest]")]),t._v(" Polly helper was renamed to MockRequest.")]),t._v(" "),e("li",[t._v("[MockRequest][WebDriver] "),e("a",{attrs:{href:"https://codecept.io/webdriver#mocking-requests",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mocking requests"),e("OutboundLink")],1),t._v(" is now available in WebDriver. Thanks "),e("strong",[e("a",{attrs:{href:"https://github.com/radhey1851",target:"_blank",rel:"noopener noreferrer"}},[t._v("radhey1851"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Ensure configured user agent and/or window size is applied to all pages. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1862",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1862"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/martomo",target:"_blank",rel:"noopener noreferrer"}},[t._v("martomo"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Improve handling of xpath locators with round brackets by "),e("strong",[e("a",{attrs:{href:"https://github.com/nitschSB",target:"_blank",rel:"noopener noreferrer"}},[t._v("nitschSB"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1870",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1870"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Use WebDriver capabilities config in wdio plugin. "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1869",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1869"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/quekshuy",target:"_blank",rel:"noopener noreferrer"}},[t._v("quekshuy"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_2-3-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-3-0"}},[t._v("#")]),t._v(" 2.3.0")]),t._v(" "),e("ul",[e("li",[e("strong",[e("a",{attrs:{href:"https://codecept.io/parallel#parallel-execution-by-workers",target:"_blank",rel:"noopener noreferrer"}},[t._v("Parallel testing by workers"),e("OutboundLink")],1),t._v(" introduced")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/VikalpP",target:"_blank",rel:"noopener noreferrer"}},[t._v("VikalpP"),e("OutboundLink")],1)]),t._v(" and "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)]),t._v(". Use "),e("code",[t._v("run-workers")]),t._v(" command as faster and simpler alternative to "),e("code",[t._v("run-multiple")]),t._v(". Requires NodeJS v12")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("# run all tests in parallel using 3 workers\nnpx codeceptjs run-workers 3\n")])])]),e("ul",[e("li",[t._v("[GraphQL][GraphQLDataFactory] "),e("strong",[t._v("Helpers for data management over GraphQL")]),t._v(" APIs added. By "),e("strong",[e("a",{attrs:{href:"https://github.com/radhey1851",target:"_blank",rel:"noopener noreferrer"}},[t._v("radhey1851"),e("OutboundLink")],1)]),t._v(".\n"),e("ul",[e("li",[t._v("Learn how to "),e("a",{attrs:{href:"https://codecept.io/data#graphql",target:"_blank",rel:"noopener noreferrer"}},[t._v("use GraphQL helper"),e("OutboundLink")],1),t._v(" to access GarphQL API")]),t._v(" "),e("li",[t._v("And how to combine it with "),e("a",{attrs:{href:"https://codecept.io/data#graphql-data-factory",target:"_blank",rel:"noopener noreferrer"}},[t._v("GraphQLDataFactory"),e("OutboundLink")],1),t._v(" to generate and persist test data.")])])]),t._v(" "),e("li",[e("strong",[t._v("Updated to use Mocha 6")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1802",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1802"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/elukoyanov",target:"_blank",rel:"noopener noreferrer"}},[t._v("elukoyanov"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("dry-run")]),t._v(" command to print steps of test scenarios without running them. Fails to execute scenarios with "),e("code",[t._v("grab*")]),t._v(" methods or custom code. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1825",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1825"),e("OutboundLink")],1),t._v(" for more details.")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("npx codeceptjs dry-run\n")])])]),e("ul",[e("li",[e("strong",[t._v("[Appium]")]),t._v(" Optimization when clicking, searching for fields by accessibility id. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1777",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1777"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/gagandeepsingh26",target:"_blank",rel:"noopener noreferrer"}},[t._v("gagandeepsingh26"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[TestCafe]")]),t._v(" Fixed "),e("code",[t._v("switchTo")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/KadoBOT",target:"_blank",rel:"noopener noreferrer"}},[t._v("KadoBOT"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Added geolocation actions by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[e("code",[t._v("grabGeoLocation()")])]),t._v(" "),e("li",[e("code",[t._v("setGeoLocation()")])])])]),t._v(" "),e("li",[e("strong",[t._v("[Polly]")]),t._v(" Check typeof arguments for mock requests by "),e("strong",[e("a",{attrs:{href:"https://github.com/VikalpP",target:"_blank",rel:"noopener noreferrer"}},[t._v("VikalpP"),e("OutboundLink")],1)]),t._v(". Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1815",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1815"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("CLI improvements by "),e("strong",[e("a",{attrs:{href:"https://github.com/jamesgeorge007",target:"_blank",rel:"noopener noreferrer"}},[t._v("jamesgeorge007"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[e("code",[t._v("codeceptjs")]),t._v(" command prints list of all available commands")]),t._v(" "),e("li",[t._v("added "),e("code",[t._v("codeceptjs -V")]),t._v(" flag to print version information")]),t._v(" "),e("li",[t._v("warns on unknown command")])])]),t._v(" "),e("li",[t._v("Added TypeScript files support to "),e("code",[t._v("run-multiple")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/z4o4z",target:"_blank",rel:"noopener noreferrer"}},[t._v("z4o4z"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed element position bug in locator builder. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1829",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1829"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/AnotherAnkor",target:"_blank",rel:"noopener noreferrer"}},[t._v("AnotherAnkor"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Various TypeScript typings updates by "),e("strong",[e("a",{attrs:{href:"https://github.com/elukoyanov",target:"_blank",rel:"noopener noreferrer"}},[t._v("elukoyanov"),e("OutboundLink")],1)]),t._v(" and "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("event.step.comment")]),t._v(" event for all comment steps like "),e("code",[t._v("I.say")]),t._v(" or gherking steps.")])]),t._v(" "),e("h2",{attrs:{id:"_2-2-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-1"}},[t._v("#")]),t._v(" 2.2.1")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" A "),e("a",{attrs:{href:"https://codecept.io/webdriver",target:"_blank",rel:"noopener noreferrer"}},[t._v("dedicated guide"),e("OutboundLink")],1),t._v(" written.")]),t._v(" "),e("li",[e("strong",[t._v("[TestCafe]")]),t._v(" A "),e("a",{attrs:{href:"https://codecept.io/testcafe",target:"_blank",rel:"noopener noreferrer"}},[t._v("dedicated guide"),e("OutboundLink")],1),t._v(" written.")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" A "),e("a",{attrs:{href:"https://codecept.io/puppeteer#mocking-requests",target:"_blank",rel:"noopener noreferrer"}},[t._v("chapter on mocking"),e("OutboundLink")],1),t._v(" written")]),t._v(" "),e("li",[t._v("[Puppeteer][Nightmare][TestCafe] Window mode is enabled by default on "),e("code",[t._v("codeceptjs init")]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[TestCafe]")]),t._v(" Actions implemented by "),e("strong",[e("a",{attrs:{href:"https://github.com/hubidu",target:"_blank",rel:"noopener noreferrer"}},[t._v("hubidu"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[e("code",[t._v("grabPageScrollPosition")])]),t._v(" "),e("li",[e("code",[t._v("scrollPageToTop")])]),t._v(" "),e("li",[e("code",[t._v("scrollPageToBottom")])]),t._v(" "),e("li",[e("code",[t._v("scrollTo")])]),t._v(" "),e("li",[e("code",[t._v("switchTo")])])])]),t._v(" "),e("li",[t._v("Intellisense improvements. Renamed "),e("code",[t._v("tsconfig.json")]),t._v(" to "),e("code",[t._v("jsconfig.json")]),t._v(" on init. Fixed autocompletion for Visual Studio Code.")]),t._v(" "),e("li",[e("strong",[t._v("[Polly]")]),t._v(" Take configuration values from Puppeteer. Fix "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1766",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1766"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/VikalpP",target:"_blank",rel:"noopener noreferrer"}},[t._v("VikalpP"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Polly]")]),t._v(" Add preconditions to check for puppeteer page availability by "),e("strong",[e("a",{attrs:{href:"https://github.com/VikalpP",target:"_blank",rel:"noopener noreferrer"}},[t._v("VikalpP"),e("OutboundLink")],1)]),t._v(". Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1767",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1767"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Use filename for "),e("code",[t._v("uploadFile")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/VikalpP",target:"_blank",rel:"noopener noreferrer"}},[t._v("VikalpP"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1797",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1797"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Configure speed of input with "),e("code",[t._v("pressKeyDelay")]),t._v(" option. By "),e("strong",[e("a",{attrs:{href:"https://github.com/hubidu",target:"_blank",rel:"noopener noreferrer"}},[t._v("hubidu"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed recursive loading of support objects by "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("Fixed support object definitions in steps.d.ts by "),e("strong",[e("a",{attrs:{href:"https://github.com/johnyb",target:"_blank",rel:"noopener noreferrer"}},[t._v("johnyb"),e("OutboundLink")],1)]),t._v(". Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1795",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1795"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Fixed "),e("code",[t._v("Data().Scenario().injectDependencies()")]),t._v(" is not a function by "),e("strong",[e("a",{attrs:{href:"https://github.com/andrerleao",target:"_blank",rel:"noopener noreferrer"}},[t._v("andrerleao"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed crash when using xScenario & Scenario.skip with tag by "),e("strong",[e("a",{attrs:{href:"https://github.com/VikalpP",target:"_blank",rel:"noopener noreferrer"}},[t._v("VikalpP"),e("OutboundLink")],1)]),t._v(". Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1751",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1751"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Dynamic configuration of helpers can be performed with async function. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1786",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1786"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/cviejo",target:"_blank",rel:"noopener noreferrer"}},[t._v("cviejo"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added TS definitions for internal objects by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("BDD improvements:\n"),e("ul",[e("li",[t._v("Fix for snippets command with a .feature file that has special characters by "),e("strong",[e("a",{attrs:{href:"https://github.com/asselin",target:"_blank",rel:"noopener noreferrer"}},[t._v("asselin"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fix "),e("code",[t._v("--path")]),t._v(" option on "),e("code",[t._v("gherkin:snippets")]),t._v(" command by "),e("strong",[e("a",{attrs:{href:"https://github.com/asselin",target:"_blank",rel:"noopener noreferrer"}},[t._v("asselin"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1790",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1790"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("--feature")]),t._v(" option to "),e("code",[t._v("gherkin:snippets")]),t._v(" to enable creating snippets for a subset of .feature files. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1803",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1803"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/asselin",target:"_blank",rel:"noopener noreferrer"}},[t._v("asselin"),e("OutboundLink")],1)]),t._v(".")])])]),t._v(" "),e("li",[t._v("Fixed: dynamic configs not reset after test. Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1776",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1776"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/cviejo",target:"_blank",rel:"noopener noreferrer"}},[t._v("cviejo"),e("OutboundLink")],1)]),t._v(".")])]),t._v(" "),e("h2",{attrs:{id:"_2-2-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-2-0"}},[t._v("#")]),t._v(" 2.2.0")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("EXPERIMENTAL")]),t._v(" "),e("a",{attrs:{href:"https://codecept.io/helpers/TestCafe",target:"_blank",rel:"noopener noreferrer"}},[e("strong",[t._v("TestCafe")]),t._v(" helper"),e("OutboundLink")],1),t._v(" introduced. TestCafe allows to run cross-browser tests it its own very fast engine. Supports all browsers including mobile. Thanks to "),e("strong",[e("a",{attrs:{href:"https://github.com/hubidu",target:"_blank",rel:"noopener noreferrer"}},[t._v("hubidu"),e("OutboundLink")],1)]),t._v(" for implementation! Please test it and send us feedback.")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Mocking requests enabled by introducing "),e("a",{attrs:{href:"https://codecept.io/helpers/Polly",target:"_blank",rel:"noopener noreferrer"}},[t._v("Polly.js helper"),e("OutboundLink")],1),t._v(". Thanks "),e("strong",[e("a",{attrs:{href:"https://github.com/VikalpP",target:"_blank",rel:"noopener noreferrer"}},[t._v("VikalpP"),e("OutboundLink")],1)])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// use Polly & Puppeteer helpers")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockRequest")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'GET'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/users'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockRequest")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'POST'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/users'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'fake'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("strong",[t._v("EXPERIMENTAL")]),t._v(" "),e("strong",[t._v("[Puppeteer]")]),t._v(" "),e("a",{attrs:{href:"https://codecept.io/helpers/Puppeteer-firefox",target:"_blank",rel:"noopener noreferrer"}},[t._v("Firefox support"),e("OutboundLink")],1),t._v(" introduced by "),e("strong",[e("a",{attrs:{href:"https://github.com/ngadiyak",target:"_blank",rel:"noopener noreferrer"}},[t._v("ngadiyak"),e("OutboundLink")],1)]),t._v(", see "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1740",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1740"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("strong",[t._v("[stepByStepReportPlugin]")]),t._v(" use md5 hash to generate reports into unique folder. Fix "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1744",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1744"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/chimurai",target:"_blank",rel:"noopener noreferrer"}},[t._v("chimurai"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Interactive pause improvements:\n"),e("ul",[e("li",[t._v("print result of "),e("code",[t._v("grab")]),t._v(" commands")]),t._v(" "),e("li",[t._v("print message for successful assertions")])])]),t._v(" "),e("li",[e("code",[t._v("run-multiple")]),t._v(" (parallel execution) improvements:\n"),e("ul",[e("li",[e("code",[t._v("bootstrapAll")]),t._v(" must be called before creating chunks. "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1741",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1741"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Bugfix: If value in config has falsy value then multiple config does not overwrite original value. "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1756",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1756"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/LukoyanovE",target:"_blank",rel:"noopener noreferrer"}},[t._v("LukoyanovE"),e("OutboundLink")],1)])])])]),t._v(" "),e("li",[t._v("Fixed hooks broken in 2.1.5 by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fix references to support objects when using Dependency Injection. Fix by "),e("strong",[e("a",{attrs:{href:"https://github.com/johnyb",target:"_blank",rel:"noopener noreferrer"}},[t._v("johnyb"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1701",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1701"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Fix dynamic config applied for multiple helpers by "),e("strong",[e("a",{attrs:{href:"https://github.com/VikalpP",target:"_blank",rel:"noopener noreferrer"}},[t._v("VikalpP"),e("OutboundLink")],1)]),t._v(" "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1743",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1743"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_2-1-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-5"}},[t._v("#")]),t._v(" 2.1.5")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("EXPERIMENTAL")]),t._v(" "),e("a",{attrs:{href:"https://github.com/codeceptjs/detox-helper",target:"_blank",rel:"noopener noreferrer"}},[t._v("Wix Detox support"),e("OutboundLink")],1),t._v(" introduced as standalone helper. Provides a faster alternative to Appium for mobile testing.")]),t._v(" "),e("li",[t._v("Saving successful commands inside interactive pause into "),e("code",[t._v("_output/cli-history")]),t._v(" file. By "),e("strong",[e("a",{attrs:{href:"https://github.com/hubidu",target:"_blank",rel:"noopener noreferrer"}},[t._v("hubidu"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed hanging error handler inside scenario. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1721",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1721"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/haily-lgc",target:"_blank",rel:"noopener noreferrer"}},[t._v("haily-lgc"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("Fixed by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)]),t._v(": tests did not fail when an exception was raised in async bootstrap.")]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Added window control methods by "),e("strong",[e("a",{attrs:{href:"https://github.com/emmonspired",target:"_blank",rel:"noopener noreferrer"}},[t._v("emmonspired"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[e("code",[t._v("grabAllWindowHandles")]),t._v(" returns all window handles")]),t._v(" "),e("li",[e("code",[t._v("grabCurrentWindowHandle")]),t._v(" returns current window handle")]),t._v(" "),e("li",[e("code",[t._v("switchToWindow")]),t._v(" switched to window by its handle")])])]),t._v(" "),e("li",[e("strong",[t._v("[Appium]")]),t._v(" Fixed using "),e("code",[t._v("host")]),t._v(" as configuration by "),e("strong",[e("a",{attrs:{href:"https://github.com/trinhpham",target:"_blank",rel:"noopener noreferrer"}},[t._v("trinhpham"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed "),e("code",[t._v("run-multiple")]),t._v(" command when "),e("code",[t._v("tests")]),t._v(" config option is undefined (in Gherkin scenarios). By "),e("strong",[e("a",{attrs:{href:"https://github.com/gkushang",target:"_blank",rel:"noopener noreferrer"}},[t._v("gkushang"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("German translation introduced by "),e("strong",[e("a",{attrs:{href:"https://github.com/hubidu",target:"_blank",rel:"noopener noreferrer"}},[t._v("hubidu"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_2-1-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-4"}},[t._v("#")]),t._v(" 2.1.4")]),t._v(" "),e("ul",[e("li",[t._v("[WebDriver][Puppeteer][Protractor][Nightmare] A11y locator support introduced by "),e("strong",[e("a",{attrs:{href:"https://github.com/Holorium",target:"_blank",rel:"noopener noreferrer"}},[t._v("Holorium"),e("OutboundLink")],1)]),t._v(". Clickable elements as well as fields can be located by following attributes:\n"),e("ul",[e("li",[e("code",[t._v("aria-label")])]),t._v(" "),e("li",[e("code",[t._v("title")])]),t._v(" "),e("li",[e("code",[t._v("aria-labelledby")])])])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Added support for React locators.\n"),e("ul",[e("li",[t._v("New "),e("a",{attrs:{href:"https://codecept.io/react",target:"_blank",rel:"noopener noreferrer"}},[t._v("React Guide"),e("OutboundLink")],1),t._v(" added.")])])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Deprecated "),e("code",[t._v("downloadFile")])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Introduced "),e("code",[t._v("handleDownloads")]),t._v(" replacing "),e("code",[t._v("downloadFile")])]),t._v(" "),e("li",[t._v("[puppeteerCoverage plugin] Fixed path already exists error by "),e("strong",[e("a",{attrs:{href:"https://github.com/seta-tuha",target:"_blank",rel:"noopener noreferrer"}},[t._v("seta-tuha"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("Fixed 'ERROR: ENAMETOOLONG' creating directory names in "),e("code",[t._v("run-multiple")]),t._v(" with long config. By "),e("strong",[e("a",{attrs:{href:"https://github.com/artvinn",target:"_blank",rel:"noopener noreferrer"}},[t._v("artvinn"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[REST]")]),t._v(" Fixed url autocompletion combining base and relative paths by "),e("strong",[e("a",{attrs:{href:"https://github.com/LukoyanovE",target:"_blank",rel:"noopener noreferrer"}},[t._v("LukoyanovE"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[Nightmare][Protractor] "),e("code",[t._v("uncheckOption")]),t._v(" method introduced by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[autoLogin plugin] Enable to use without "),e("code",[t._v("await")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/tsuemura",target:"_blank",rel:"noopener noreferrer"}},[t._v("tsuemura"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed "),e("code",[t._v('UnhandledPromiseRejectionWarning: "Execution context was destroyed...')]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/adrielcodeco",target:"_blank",rel:"noopener noreferrer"}},[t._v("adrielcodeco"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Keep browser window dimensions when starting a new session by "),e("strong",[e("a",{attrs:{href:"https://github.com/spiroid",target:"_blank",rel:"noopener noreferrer"}},[t._v("spiroid"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Replace Ghekrin plceholders with values in files that combine a scenerio outline and table by "),e("strong",[e("a",{attrs:{href:"https://github.com/medtoure18",target:"_blank",rel:"noopener noreferrer"}},[t._v("medtoure18"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("Added Documentation to "),e("a",{attrs:{href:"https://codecept.io/mobile-react-native-locators",target:"_blank",rel:"noopener noreferrer"}},[t._v("locate elements in React Native"),e("OutboundLink")],1),t._v(" apps. By "),e("strong",[e("a",{attrs:{href:"https://github.com/DimGun",target:"_blank",rel:"noopener noreferrer"}},[t._v("DimGun"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("Adding optional "),e("code",[t._v("path")]),t._v(" parameter to "),e("code",[t._v("bdd:snippets")]),t._v(" command to append snippets to a specific file. By "),e("strong",[e("a",{attrs:{href:"https://github.com/cthorsen31",target:"_blank",rel:"noopener noreferrer"}},[t._v("cthorsen31"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("Added optional "),e("code",[t._v("output")]),t._v(" parameter to "),e("code",[t._v("def")]),t._v(" command by "),e("strong",[e("a",{attrs:{href:"https://github.com/LukoyanovE",target:"_blank",rel:"noopener noreferrer"}},[t._v("LukoyanovE"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Added "),e("code",[t._v("grabDataFromPerformanceTiming")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("axios updated to "),e("code",[t._v("0.19.0")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/SteveShaffer",target:"_blank",rel:"noopener noreferrer"}},[t._v("SteveShaffer"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("TypeScript defitions updated by "),e("strong",[e("a",{attrs:{href:"https://github.com/LukoyanovE",target:"_blank",rel:"noopener noreferrer"}},[t._v("LukoyanovE"),e("OutboundLink")],1)]),t._v(". Added "),e("code",[t._v("secret")]),t._v(" and "),e("code",[t._v("inject")]),t._v(" function.")])]),t._v(" "),e("h2",{attrs:{id:"_2-1-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-3"}},[t._v("#")]),t._v(" 2.1.3")]),t._v(" "),e("ul",[e("li",[t._v("Fixed autoLogin plugin to inject "),e("code",[t._v("login")]),t._v(" function")]),t._v(" "),e("li",[t._v("Fixed using "),e("code",[t._v("toString()")]),t._v(" in DataTablewhen it is defined by "),e("strong",[e("a",{attrs:{href:"https://github.com/tsuemura",target:"_blank",rel:"noopener noreferrer"}},[t._v("tsuemura"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_2-1-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-2"}},[t._v("#")]),t._v(" 2.1.2")]),t._v(" "),e("ul",[e("li",[t._v("Fixed "),e("code",[t._v("inject")]),t._v(" to load objects recursively.")]),t._v(" "),e("li",[t._v("Fixed TypeScript definitions for locators by "),e("strong",[e("a",{attrs:{href:"https://github.com/LukoyanovE",target:"_blank",rel:"noopener noreferrer"}},[t._v("LukoyanovE"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("EXPERIMENTAL")]),t._v(" "),e("strong",[t._v("[WebDriver]")]),t._v(" ReactJS locators support with webdriverio v5.8+:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locating React element by name, prop, state")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("react")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'component-name'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("props")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("state")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("react")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'component-name'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("props")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("state")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h2",{attrs:{id:"_2-1-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-1"}},[t._v("#")]),t._v(" 2.1.1")]),t._v(" "),e("ul",[e("li",[t._v("Do not retry "),e("code",[t._v("within")]),t._v(" and "),e("code",[t._v("session")]),t._v(" calls inside "),e("code",[t._v("retryFailedStep")]),t._v(" plugin. Fix by "),e("strong",[e("a",{attrs:{href:"https://github.com/tsuemura",target:"_blank",rel:"noopener noreferrer"}},[t._v("tsuemura"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_2-1-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-1-0"}},[t._v("#")]),t._v(" 2.1.0")]),t._v(" "),e("ul",[e("li",[t._v("Added global "),e("code",[t._v("inject()")]),t._v(" function to require actor and page objects using dependency injection. Recommended to use in page objects, step definition files, support objects:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// old way")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("actor")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" myPage "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'../page/myPage'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// new way")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" myPage "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("inject")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Added global "),e("code",[t._v("secret")]),t._v(" function to fill in sensitive data. By "),e("strong",[e("a",{attrs:{href:"https://github.com/RohanHart",target:"_blank",rel:"noopener noreferrer"}},[t._v("RohanHart"),e("OutboundLink")],1)]),t._v(":")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("secret")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'123456'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("a",{attrs:{href:"https://codecept.io/plugins/#wdio",target:"_blank",rel:"noopener noreferrer"}},[t._v("wdioPlugin"),e("OutboundLink")],1),t._v(" Added a plugin to "),e("strong",[t._v("support webdriverio services")]),t._v(" including "),e("em",[t._v("selenium-standalone")]),t._v(", "),e("em",[t._v("sauce")]),t._v(", "),e("em",[t._v("browserstack")]),t._v(", etc. "),e("strong",[t._v("Sponsored by "),e("strong",[e("a",{attrs:{href:"https://github.com/GSasu",target:"_blank",rel:"noopener noreferrer"}},[t._v("GSasu"),e("OutboundLink")],1)])])]),t._v(" "),e("li",[e("strong",[t._v("[Appium]")]),t._v(" Fixed "),e("code",[t._v("swipe*")]),t._v(" methods by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("BDD Gherkin Improvements:\n"),e("ul",[e("li",[t._v("Implemented "),e("code",[t._v("run-multiple")]),t._v(" for feature files. "),e("strong",[t._v("Sponsored by "),e("strong",[e("a",{attrs:{href:"https://github.com/GSasu",target:"_blank",rel:"noopener noreferrer"}},[t._v("GSasu"),e("OutboundLink")],1)])])]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("--features")]),t._v(" and "),e("code",[t._v("--tests")]),t._v(" options to "),e("code",[t._v("run-multiple")]),t._v(". "),e("strong",[t._v("Sponsored by "),e("strong",[e("a",{attrs:{href:"https://github.com/GSasu",target:"_blank",rel:"noopener noreferrer"}},[t._v("GSasu"),e("OutboundLink")],1)])])]),t._v(" "),e("li",[t._v("Implemented "),e("code",[t._v("Before")]),t._v(" and "),e("code",[t._v("After")]),t._v(" hooks in "),e("a",{attrs:{href:"https://codecept.io/bdd#before",target:"_blank",rel:"noopener noreferrer"}},[t._v("step definitions"),e("OutboundLink")],1)])])]),t._v(" "),e("li",[t._v("Fixed running tests by absolute path. By "),e("strong",[e("a",{attrs:{href:"https://github.com/batalov",target:"_blank",rel:"noopener noreferrer"}},[t._v("batalov"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("Enabled the adding screenshot to failed test for moch-junit-reporter by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Implemented "),e("code",[t._v("uncheckOption")]),t._v(" and fixed behavior of "),e("code",[t._v("checkOption")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/aml2610",target:"_blank",rel:"noopener noreferrer"}},[t._v("aml2610"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Fixed "),e("code",[t._v("seeTextEquals")]),t._v(" on empty strings by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed launch with "),e("code",[t._v("browserWSEndpoint")]),t._v(" config by "),e("strong",[e("a",{attrs:{href:"https://github.com/ngadiyak",target:"_blank",rel:"noopener noreferrer"}},[t._v("ngadiyak"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed switching back to main window in multi-session mode by "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[autoLoginPlugin]")]),t._v(" Fixed using async functions for auto login by "),e("strong",[e("a",{attrs:{href:"https://github.com/nitschSB",target:"_blank",rel:"noopener noreferrer"}},[t._v("nitschSB"),e("OutboundLink")],1)])])]),t._v(" "),e("blockquote",[e("p",[t._v("This release was partly sponsored by "),e("strong",[e("a",{attrs:{href:"https://github.com/GSasu",target:"_blank",rel:"noopener noreferrer"}},[t._v("GSasu"),e("OutboundLink")],1)]),t._v(". Thanks for the support!\nDo you want to improve this project? [Learn more about sponsorin CodeceptJS")])]),t._v(" "),e("h2",{attrs:{id:"_2-0-8"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-0-8"}},[t._v("#")]),t._v(" 2.0.8")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Added "),e("code",[t._v("downloadFile")]),t._v(" action by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(".")])]),t._v(" "),e("p",[t._v("Use it with "),e("code",[t._v("FileSystem")]),t._v(" helper to test availability of a file:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" fileName "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("downloadFile")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'a.file-link'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amInPath")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'output'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeFile")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("fileName"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("blockquote",[e("p",[t._v("Actions "),e("code",[t._v("amInPath")]),t._v(" and "),e("code",[t._v("seeFile")]),t._v(" are taken from "),e("a",{attrs:{href:"https://codecept.io/helpers/FileSystem",target:"_blank",rel:"noopener noreferrer"}},[t._v("FileSystem"),e("OutboundLink")],1),t._v(" helper")])]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed "),e("code",[t._v("autoLogin")]),t._v(" plugin with Puppeteer by "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" "),e("code",[t._v("seeInField")]),t._v(" should throw error if element has no value attrubite. By "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Fixed "),e("code",[t._v("seeTextEquals")]),t._v(" passes for any string if element is empty by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Internal refctoring to use "),e("code",[t._v("el.isDisplayed")]),t._v(" to match latest webdriverio implementation. Thanks to "),e("strong",[e("a",{attrs:{href:"https://github.com/LukoyanovE",target:"_blank",rel:"noopener noreferrer"}},[t._v("LukoyanovE"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[allure plugin] Add ability enable "),e("a",{attrs:{href:"https://github.com/allure-framework/allure2/blob/master/plugins/screen-diff-plugin/README.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("screenshotDiff plugin"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Appium]")]),t._v(" Fixed "),e("code",[t._v("locator.stringify")]),t._v(" call by "),e("strong",[e("a",{attrs:{href:"https://github.com/LukoyanovE",target:"_blank",rel:"noopener noreferrer"}},[t._v("LukoyanovE"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_2-0-7"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-0-7"}},[t._v("#")]),t._v(" 2.0.7")]),t._v(" "),e("ul",[e("li",[t._v("[WebDriver][Protractor][Nightmare] "),e("code",[t._v("rightClick")]),t._v(" method implemented (fixed) in a standard way. By "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Updated WebDriver API calls in helper. By "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[stepByStepReportPlugin]")]),t._v(" Added "),e("code",[t._v("screenshotsForAllureReport")]),t._v(" config options to automatically attach screenshots to allure reports. By "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[allurePlugin]")]),t._v(" Added "),e("code",[t._v("addLabel")]),t._v(" method by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Locator Builder: fixed "),e("code",[t._v("withChild")]),t._v(" and "),e("code",[t._v("withDescendant")]),t._v(" to match deep nested siblings by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)]),t._v(".")])]),t._v(" "),e("h2",{attrs:{id:"_2-0-6"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-0-6"}},[t._v("#")]),t._v(" 2.0.6")]),t._v(" "),e("ul",[e("li",[t._v("Introduced "),e("a",{attrs:{href:"https://codecept.io/locators#custom-locators",target:"_blank",rel:"noopener noreferrer"}},[t._v("Custom Locator Strategies"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[t._v("Added "),e("a",{attrs:{href:"https://codecept.io/visual",target:"_blank",rel:"noopener noreferrer"}},[t._v("Visual Testing Guide"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/puneet0191",target:"_blank",rel:"noopener noreferrer"}},[t._v("puneet0191"),e("OutboundLink")],1)]),t._v(" and "),e("strong",[e("a",{attrs:{href:"https://github.com/MitkoTschimev",target:"_blank",rel:"noopener noreferrer"}},[t._v("MitkoTschimev"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" "),e("a",{attrs:{href:"https://codecept.io/plugins#puppeteercoverage",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("puppeteerCoverage")]),e("OutboundLink")],1),t._v(" plugin added to collect code coverage in JS. By "),e("strong",[e("a",{attrs:{href:"https://github.com/dvillarama",target:"_blank",rel:"noopener noreferrer"}},[t._v("dvillarama"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Make override option in "),e("code",[t._v("run-multiple")]),t._v(" to respect the generated overridden config by "),e("strong",[e("a",{attrs:{href:"https://github.com/kinyat",target:"_blank",rel:"noopener noreferrer"}},[t._v("kinyat"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed deep merge for "),e("code",[t._v("container.append()")]),t._v(". Introduced "),e("code",[t._v("lodash.merge()")]),t._v(". By "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed saving screenshot on Windows by")]),t._v(" "),e("li",[t._v("Fix errors on using interactive shell with Allure plugin by tsuemura")]),t._v(" "),e("li",[t._v("Fixed using dynamic injections with "),e("code",[t._v("Scenario().injectDependencies")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/tsemura",target:"_blank",rel:"noopener noreferrer"}},[t._v("tsemura"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[WebDriver][Puppeteer][Nightmare][Protractor] Fixed url protocol detection for non-http urls by "),e("strong",[e("a",{attrs:{href:"https://github.com/LukoyanovE",target:"_blank",rel:"noopener noreferrer"}},[t._v("LukoyanovE"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Enabled compatibility with "),e("code",[t._v("stepByStepReport")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/tsuemura",target:"_blank",rel:"noopener noreferrer"}},[t._v("tsuemura"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Fixed "),e("code",[t._v("grabHTMLFrom")]),t._v(" to return innerHTML value by "),e("strong",[e("a",{attrs:{href:"https://github.com/Holorium",target:"_blank",rel:"noopener noreferrer"}},[t._v("Holorium"),e("OutboundLink")],1)]),t._v(". Fixed compatibility with WebDriverIO.")]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" "),e("code",[t._v("grabHTMLFrom")]),t._v(" to return one HTML vlaue for one element matched, array if multiple elements found by "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Added "),e("code",[t._v("grabHTMLFrom")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed "),e("code",[t._v("bootstrapAll")]),t._v(" and "),e("code",[t._v("teardownAll")]),t._v(" launch with path as argument by "),e("strong",[e("a",{attrs:{href:"https://github.com/LukoyanovE",target:"_blank",rel:"noopener noreferrer"}},[t._v("LukoyanovE"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed "),e("code",[t._v("bootstrapAll")]),t._v(" and "),e("code",[t._v("teardownAll")]),t._v(" calls from exported object by "),e("strong",[e("a",{attrs:{href:"https://github.com/LukoyanovE",target:"_blank",rel:"noopener noreferrer"}},[t._v("LukoyanovE"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Added possibility to define conditional checks interval for "),e("code",[t._v("waitUntil")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/LukoyanovE",target:"_blank",rel:"noopener noreferrer"}},[t._v("LukoyanovE"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed storing current data in data driven tests in a test object. By "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Fixed "),e("code",[t._v("hostname")]),t._v(" config option overwrite when setting a cloud provider. By "),e("strong",[e("a",{attrs:{href:"https://github.com/LukoyanovE",target:"_blank",rel:"noopener noreferrer"}},[t._v("LukoyanovE"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" "),e("code",[t._v("dragSlider")]),t._v(" method implemented by "),e("strong",[e("a",{attrs:{href:"https://github.com/DavertMik",target:"_blank",rel:"noopener noreferrer"}},[t._v("DavertMik"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDrover]")]),t._v(" Fixed "),e("code",[t._v("scrollTo")]),t._v(" to use new webdriverio API by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added Japanese translation file by "),e("strong",[e("a",{attrs:{href:"https://github.com/tsemura",target:"_blank",rel:"noopener noreferrer"}},[t._v("tsemura"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("Locator.withDescendant()")]),t._v(" method to find an element which contains a descendant (child, grandchild) by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Fixed configuring capabilities for Selenoid and IE by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Restore original window size when taking full size screenshot by "),e("strong",[e("a",{attrs:{href:"https://github.com/tsuemura",target:"_blank",rel:"noopener noreferrer"}},[t._v("tsuemura"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Enabled "),e("code",[t._v("throws()")]),t._v(","),e("code",[t._v("fails()")]),t._v(", "),e("code",[t._v("retry()")]),t._v(", "),e("code",[t._v("timeout()")]),t._v(", "),e("code",[t._v("config()")]),t._v(" functions for data driven tests. By "),e("strong",[e("a",{attrs:{href:"https://github.com/jjm409",target:"_blank",rel:"noopener noreferrer"}},[t._v("jjm409"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_2-0-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-0-5"}},[t._v("#")]),t._v(" 2.0.5")]),t._v(" "),e("p",[t._v("[Broken Release]")]),t._v(" "),e("h2",{attrs:{id:"_2-0-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-0-4"}},[t._v("#")]),t._v(" 2.0.4")]),t._v(" "),e("ul",[e("li",[t._v("[WebDriver][Protractor][Nightmare][Puppeteer] "),e("code",[t._v("grabAttributeFrom")]),t._v(" returns an array when multiple elements matched. By "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[autoLogin plugin] Fixed merging users config by "),e("strong",[e("a",{attrs:{href:"https://github.com/nealfennimore",target:"_blank",rel:"noopener noreferrer"}},[t._v("nealfennimore"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[autoDelay plugin] Added WebDriver to list of supported helpers by "),e("strong",[e("a",{attrs:{href:"https://github.com/mattin4d",target:"_blank",rel:"noopener noreferrer"}},[t._v("mattin4d"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Appium]")]),t._v(" Fixed using locators in "),e("code",[t._v("waitForElement")]),t._v(", "),e("code",[t._v("waitForVisible")]),t._v(", "),e("code",[t._v("waitForInvisible")]),t._v(". By "),e("strong",[e("a",{attrs:{href:"https://github.com/eduardofinotti",target:"_blank",rel:"noopener noreferrer"}},[t._v("eduardofinotti"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[allure plugin] Add tags to allure reports by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[allure plugin] Add skipped tests to allure reports by "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed "),e("code",[t._v("Logged Test name | [object Object]")]),t._v(" when used Data().Scenario(). By "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed Data().only.Scenario() to run for all datasets. By "),e("strong",[e("a",{attrs:{href:"https://github.com/Vorobeyko",target:"_blank",rel:"noopener noreferrer"}},[t._v("Vorobeyko"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" "),e("code",[t._v("attachFile")]),t._v(" to work with hidden elements. Fixed in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1460",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1460"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/tsuemura",target:"_blank",rel:"noopener noreferrer"}},[t._v("tsuemura"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_2-0-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-0-3"}},[t._v("#")]),t._v(" 2.0.3")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://codecept.io/plugins#autologin",target:"_blank",rel:"noopener noreferrer"}},[e("strong",[t._v("autoLogin plugin")]),e("OutboundLink")],1),t._v(" added. Allows to log in once and reuse browser session. When session expires - automatically logs in again. Can persist session between runs by saving cookies to file.")]),t._v(" "),e("li",[t._v("Fixed "),e("code",[t._v("Maximum stack trace")]),t._v(" issue in "),e("code",[t._v("retryFailedStep")]),t._v(" plugin.")]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("locate()")]),t._v(" function into the interactive shell.")]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Disabled smartWait for interactive shell.")]),t._v(" "),e("li",[e("strong",[t._v("[Appium]")]),t._v(" Updated methods to use for mobile locators\n"),e("ul",[e("li",[e("code",[t._v("waitForElement")])]),t._v(" "),e("li",[e("code",[t._v("waitForVisible")])]),t._v(" "),e("li",[e("code",[t._v("waitForInvisible")])])])]),t._v(" "),e("li",[t._v("Helper and page object generators no longer update config automatically. Please add your page objects and helpers manually.")])]),t._v(" "),e("h2",{attrs:{id:"_2-0-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-0-2"}},[t._v("#")]),t._v(" 2.0.2")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Improved handling of connection with remote browser using Puppeteer by "),e("strong",[e("a",{attrs:{href:"https://github.com/martomo",target:"_blank",rel:"noopener noreferrer"}},[t._v("martomo"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Updated to webdriverio 5.2.2 by "),e("strong",[e("a",{attrs:{href:"https://github.com/martomo",target:"_blank",rel:"noopener noreferrer"}},[t._v("martomo"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Interactive pause improvements by "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[t._v("Disable retryFailedStep plugin in in interactive mode")]),t._v(" "),e("li",[t._v("Removes "),e("code",[t._v("Interface: parseInput")]),t._v(" while in interactive pause")])])]),t._v(" "),e("li",[e("strong",[t._v("[ApiDataFactory]")]),t._v(" Improvements\n"),e("ul",[e("li",[t._v("added "),e("code",[t._v("fetchId")]),t._v(" config option to override id retrieval from payload")]),t._v(" "),e("li",[t._v("added "),e("code",[t._v("onRequest")]),t._v(" config option to update request in realtime")]),t._v(" "),e("li",[t._v("added "),e("code",[t._v("returnId")]),t._v(" config option to return ids of created items instead of items themvelves")]),t._v(" "),e("li",[t._v("added "),e("code",[t._v("headers")]),t._v(" config option to override default headers.")]),t._v(" "),e("li",[t._v("added a new chapter into "),e("a",{attrs:{href:"https://codecept.io/data#api-requests-using-browser-session",target:"_blank",rel:"noopener noreferrer"}},[t._v("DataManagement"),e("OutboundLink")],1)])])]),t._v(" "),e("li",[e("strong",[t._v("[REST]")]),t._v(" Added "),e("code",[t._v("onRequest")]),t._v(" config option")])]),t._v(" "),e("h2",{attrs:{id:"_2-0-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-0-1"}},[t._v("#")]),t._v(" 2.0.1")]),t._v(" "),e("ul",[e("li",[t._v("Fixed creating project with "),e("code",[t._v("codecept init")]),t._v(".")]),t._v(" "),e("li",[t._v("Fixed error while installing webdriverio@5.")]),t._v(" "),e("li",[t._v("Added code beautifier for generated configs.")]),t._v(" "),e("li",[e("strong",[t._v("[WebDriver]")]),t._v(" Updated to webdriverio 5.1.0")])]),t._v(" "),e("h2",{attrs:{id:"_2-0-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_2-0-0"}},[t._v("#")]),t._v(" 2.0.0")]),t._v(" "),e("ul",[e("li",[e("p",[e("strong",[t._v("[WebDriver]")]),t._v(" "),e("strong",[t._v("Breaking Change.")]),t._v(" Updated to webdriverio v5. New helper "),e("strong",[t._v("WebDriver")]),t._v(" helper introduced.")]),t._v(" "),e("ul",[e("li",[e("p",[e("strong",[t._v("Upgrade plan")]),t._v(":")]),t._v(" "),e("ol",[e("li",[t._v("Install latest webdriverio")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("npm install webdriverio@5 --save\n")])])]),e("ol",{attrs:{start:"2"}},[e("li",[t._v("Replace "),e("code",[t._v("WebDriverIO")]),t._v(" => "),e("code",[t._v("WebDriver")]),t._v(" helper name in config.")]),t._v(" "),e("li",[t._v("Read "),e("a",{attrs:{href:"https://github.com/webdriverio/webdriverio/blob/master/CHANGELOG.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("webdriverio changelog"),e("OutboundLink")],1),t._v(". If you were using webdriver API in your helpers, upgrade accordingly.")]),t._v(" "),e("li",[t._v("We made WebDriver helper to be compatible with old API so no additional changes required.")])]),t._v(" "),e("blockquote",[e("p",[t._v("If you face issues using webdriverio v5 you can still use webdriverio 4.x and WebDriverIO helper. Make sure you have "),e("code",[t._v("webdriverio: ^4.0")]),t._v(" installed.")])])]),t._v(" "),e("li",[e("p",[t._v("Known issues: "),e("code",[t._v("attachFile")]),t._v(" doesn't work with proxy server.")])])])]),t._v(" "),e("li",[e("p",[e("strong",[t._v("[Appium]")]),t._v(" "),e("strong",[t._v("Breaking Change.")]),t._v(" Updated to use webdriverio v5 as well. See upgrade plan ↑")])]),t._v(" "),e("li",[e("p",[e("strong",[t._v("[REST]")]),t._v(" "),e("strong",[t._v("Breaking Change.")]),t._v(" Replaced "),e("code",[t._v("unirest")]),t._v(" library with "),e("code",[t._v("axios")]),t._v(".")]),t._v(" "),e("ul",[e("li",[e("p",[e("strong",[t._v("Upgrade plan")]),t._v(":")]),t._v(" "),e("ol",[e("li",[t._v("Refer to "),e("a",{attrs:{href:"https://github.com/axios/axios",target:"_blank",rel:"noopener noreferrer"}},[t._v("axios API"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[t._v("If you were using "),e("code",[t._v("unirest")]),t._v(" requests/responses in your tests change them to axios format.")])])])])]),t._v(" "),e("li",[e("p",[e("strong",[t._v("Breaking Change.")]),t._v(" Generators support in tests removed. Use "),e("code",[t._v("async/await")]),t._v(" in your tests")])]),t._v(" "),e("li",[e("p",[e("strong",[t._v("Using "),e("code",[t._v("codecept.conf.js")]),t._v(" as default configuration format")])])]),t._v(" "),e("li",[e("p",[t._v('Fixed "enametoolong" error when saving screenshots for data driven tests by '),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])])]),t._v(" "),e("li",[e("p",[t._v("Updated NodeJS to 10 in Docker image")])]),t._v(" "),e("li",[e("p",[e("strong",[t._v("[Pupeteer]")]),t._v(" Add support to use WSEndpoint. Allows to execute tests remotely. [See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1350",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1350"),e("OutboundLink")],1),t._v("] by "),e("strong",[e("a",{attrs:{href:"https://github.com/gabrielcaires",target:"_blank",rel:"noopener noreferrer"}},[t._v("gabrielcaires"),e("OutboundLink")],1)]),t._v(" (https://github.com/codeceptjs/CodeceptJS/pull/1350)")])]),t._v(" "),e("li",[e("p",[t._v("In interactive shell "),e("strong",[t._v("[Enter]")]),t._v(" goes to next step. Improvement by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(".")])]),t._v(" "),e("li",[e("p",[e("code",[t._v("I.say")]),t._v(" accepts second parameter as color to print colorful comments. Improvement by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(".")])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("say")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'This is red'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'red'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//red is used")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("say")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'This is blue'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'blue'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//blue is used")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("say")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'This is by default'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("//cyan is used")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Fixed allure reports for multi session testing by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed allure reports for hooks by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_1-4-6"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-4-6"}},[t._v("#")]),t._v(" 1.4.6")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" "),e("code",[t._v("dragSlider")]),t._v(" action added by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed opening browser in shell mode by "),e("strong",[e("a",{attrs:{href:"https://github.com/allenhwkim",target:"_blank",rel:"noopener noreferrer"}},[t._v("allenhwkim"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed making screenshot on additional sessions by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)]),t._v(". Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1266",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1266"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("--invert")]),t._v(" option to "),e("code",[t._v("run-multiple")]),t._v(" command by "),e("strong",[e("a",{attrs:{href:"https://github.com/LukoyanovE",target:"_blank",rel:"noopener noreferrer"}},[t._v("LukoyanovE"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed steps in Allure reports by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Add option "),e("code",[t._v("output")]),t._v(" to customize output directory in "),e("a",{attrs:{href:"https://codecept.io/plugins/#stepbystepreport",target:"_blank",rel:"noopener noreferrer"}},[t._v("stepByStepReport plugin"),e("OutboundLink")],1),t._v(". By "),e("strong",[e("a",{attrs:{href:"https://github.com/fpsthirty",target:"_blank",rel:"noopener noreferrer"}},[t._v("fpsthirty"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Changed type definition of PageObjects to get auto completion by "),e("strong",[e("a",{attrs:{href:"https://github.com/rhicu",target:"_blank",rel:"noopener noreferrer"}},[t._v("rhicu"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed steps output for async/arrow functions in CLI by "),e("strong",[e("a",{attrs:{href:"https://github.com/LukoyanovE",target:"_blank",rel:"noopener noreferrer"}},[t._v("LukoyanovE"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1329",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1329"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_1-4-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-4-5"}},[t._v("#")]),t._v(" 1.4.5")]),t._v(" "),e("ul",[e("li",[t._v("Add "),e("strong",[t._v("require")]),t._v(" param to main config. Allows to require Node modules before executing tests. By "),e("strong",[e("a",{attrs:{href:"https://github.com/LukoyanovE",target:"_blank",rel:"noopener noreferrer"}},[t._v("LukoyanovE"),e("OutboundLink")],1)]),t._v(". For example:\n"),e("ul",[e("li",[t._v("Use "),e("code",[t._v("ts-node/register")]),t._v(" to register TypeScript parser")]),t._v(" "),e("li",[t._v("Use "),e("code",[t._v("should")]),t._v(" to register should-style assertions")])])])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"require"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ts-node/register"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"should"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n")])])]),e("ul",[e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" Fix timeouts definition to be compatible with W3C drivers. By "),e("strong",[e("a",{attrs:{href:"https://github.com/LukoyanovE",target:"_blank",rel:"noopener noreferrer"}},[t._v("LukoyanovE"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed: exception in Before block w/ Mocha causes test not to report failure. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1292",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1292"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Command "),e("code",[t._v("run-parallel")]),t._v(" now accepts "),e("code",[t._v("--override")]),t._v(" flag. Thanks to "),e("strong",[e("a",{attrs:{href:"https://github.com/ClemCB",target:"_blank",rel:"noopener noreferrer"}},[t._v("ClemCB"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed Allure report with Before/BeforeSuite/After/AfterSuite steps. By "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("RUN_MULTIPLE")]),t._v(" env variable to "),e("a",{attrs:{href:"https://codecept.io/docker/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Docker config"),e("OutboundLink")],1),t._v(". Allows to run tests in parallel inside a container. Thanks to "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Mochawesome]")]),t._v(" Fixed showing screenshot on failure. Fix by "),e("strong",[e("a",{attrs:{href:"https://github.com/PeterNgTr",target:"_blank",rel:"noopener noreferrer"}},[t._v("PeterNgTr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed running tests filtering by tag names defined via "),e("code",[t._v("Scenario.tag()")])])]),t._v(" "),e("h2",{attrs:{id:"_1-4-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-4-4"}},[t._v("#")]),t._v(" 1.4.4")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://codecept.io/plugins/#autoDelay",target:"_blank",rel:"noopener noreferrer"}},[t._v("autoDelay plugin"),e("OutboundLink")],1),t._v(" added. Adds tiny delay before and after an action so the page could react to actions performed.")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" improvements by "),e("strong",[e("a",{attrs:{href:"https://github.com/luismanuel001",target:"_blank",rel:"noopener noreferrer"}},[t._v("luismanuel001"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[e("code",[t._v("click")]),t._v(" no longer waits for navigation")]),t._v(" "),e("li",[e("code",[t._v("clickLink")]),t._v(" method added. Performs a click and waits for navigation.")])])]),t._v(" "),e("li",[t._v("Bootstrap scripts to be started only for "),e("code",[t._v("run")]),t._v(" command and ignored on "),e("code",[t._v("list")]),t._v(", "),e("code",[t._v("def")]),t._v(", etc. Fix by "),e("strong",[e("a",{attrs:{href:"https://github.com/LukoyanovE",target:"_blank",rel:"noopener noreferrer"}},[t._v("LukoyanovE"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_1-4-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-4-3"}},[t._v("#")]),t._v(" 1.4.3")]),t._v(" "),e("ul",[e("li",[t._v("Groups renamed to Tags for compatibility with BDD layer")]),t._v(" "),e("li",[t._v("Test and suite objects to contain tags property which can be accessed from internal API")]),t._v(" "),e("li",[t._v("Fixed adding tags for Scenario Outline in BDD")]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("tag()")]),t._v(" method to ScenarioConfig and FeatureConfig:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'update user profile'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// test goes here")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("tag")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@slow'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Fixed attaching Allure screenshot on exception. Fix by "),e("strong",[e("a",{attrs:{href:"https://github.com/DevinWatson",target:"_blank",rel:"noopener noreferrer"}},[t._v("DevinWatson"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Improved type definitions for custom steps. By "),e("strong",[e("a",{attrs:{href:"https://github.com/Akxe",target:"_blank",rel:"noopener noreferrer"}},[t._v("Akxe"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed setting "),e("code",[t._v("multiple.parallel.chunks")]),t._v(" as environment variable in config. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1238",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1238"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/ngadiyak",target:"_blank",rel:"noopener noreferrer"}},[t._v("ngadiyak"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_1-4-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-4-2"}},[t._v("#")]),t._v(" 1.4.2")]),t._v(" "),e("ul",[e("li",[t._v("Fixed setting config for plugins (inclunding setting "),e("code",[t._v("outputDir")]),t._v(" for allure) by "),e("strong",[e("a",{attrs:{href:"https://github.com/jplegoff",target:"_blank",rel:"noopener noreferrer"}},[t._v("jplegoff"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_1-4-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-4-1"}},[t._v("#")]),t._v(" 1.4.1")]),t._v(" "),e("ul",[e("li",[t._v("Added "),e("code",[t._v("plugins")]),t._v(" option to "),e("code",[t._v("run-multiple")])]),t._v(" "),e("li",[t._v("Minor output fixes")]),t._v(" "),e("li",[t._v("Added Type Definition for Helper class by "),e("strong",[e("a",{attrs:{href:"https://github.com/Akxe",target:"_blank",rel:"noopener noreferrer"}},[t._v("Akxe"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed extracing devault extension in generators by "),e("strong",[e("a",{attrs:{href:"https://github.com/Akxe",target:"_blank",rel:"noopener noreferrer"}},[t._v("Akxe"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_1-4-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-4-0"}},[t._v("#")]),t._v(" 1.4.0")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"https://codecept.io/reports/#allure",target:"_blank",rel:"noopener noreferrer"}},[e("strong",[t._v("Allure Reporter Integration")]),e("OutboundLink")],1),t._v(". Full inegration with Allure Server. Get nicely looking UI for tests,including steps, nested steps, and screenshots. Thanks "),e("strong",[t._v("Natarajan Krishnamurthy "),e("strong",[e("a",{attrs:{href:"https://github.com/krish",target:"_blank",rel:"noopener noreferrer"}},[t._v("krish"),e("OutboundLink")],1)])]),t._v(" for sponsoring this feature.")]),t._v(" "),e("li",[e("a",{attrs:{href:"https://codecept.io/hooks/#plugins",target:"_blank",rel:"noopener noreferrer"}},[t._v("Plugins API introduced"),e("OutboundLink")],1),t._v(". Create custom plugins for CodeceptJS by hooking into event dispatcher, and using promise recorder.")]),t._v(" "),e("li",[e("strong",[t._v("Official "),e("a",{attrs:{href:"https://codecept.io/plugins",target:"_blank",rel:"noopener noreferrer"}},[t._v("CodeceptJS plugins"),e("OutboundLink")],1),t._v(" added")]),t._v(":\n"),e("ul",[e("li",[e("strong",[e("code",[t._v("stepByStepReport")]),t._v(" - creates nicely looking report to see test execution as a slideshow")]),t._v(". Use this plugin to debug tests in headless environment without recording a video.")]),t._v(" "),e("li",[e("code",[t._v("allure")]),t._v(" - Allure reporter added as plugin.")]),t._v(" "),e("li",[e("code",[t._v("screenshotOnFail")]),t._v(" - saves screenshot on fail. Replaces similar functionality from helpers.")]),t._v(" "),e("li",[e("code",[t._v("retryFailedStep")]),t._v(" - to rerun each failed step.")])])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fix "),e("code",[t._v("executeAsyncScript")]),t._v(" unexpected token by "),e("strong",[e("a",{attrs:{href:"https://github.com/jonathanz",target:"_blank",rel:"noopener noreferrer"}},[t._v("jonathanz"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("override")]),t._v(" option to "),e("code",[t._v("run-multiple")]),t._v(" command by "),e("strong",[e("a",{attrs:{href:"https://github.com/svarlet",target:"_blank",rel:"noopener noreferrer"}},[t._v("svarlet"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_1-3-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-3"}},[t._v("#")]),t._v(" 1.3.3")]),t._v(" "),e("ul",[e("li",[t._v("Added "),e("code",[t._v("initGlobals()")]),t._v(" function to API of "),e("a",{attrs:{href:"https://codecept.io/hooks/#custom-runner",target:"_blank",rel:"noopener noreferrer"}},[t._v("custom runner"),e("OutboundLink")],1),t._v(".")])]),t._v(" "),e("h2",{attrs:{id:"_1-3-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-2"}},[t._v("#")]),t._v(" 1.3.2")]),t._v(" "),e("ul",[e("li",[t._v("Interactve Shell improvements for "),e("code",[t._v("pause()")]),t._v(" "),e("ul",[e("li",[t._v("Added "),e("code",[t._v("next")]),t._v(" command for "),e("strong",[t._v("step-by-step debug")]),t._v(" when using "),e("code",[t._v("pause()")]),t._v(".")]),t._v(" "),e("li",[t._v("Use "),e("code",[t._v("After(pause);")]),t._v(" in a to start interactive console after last step.")])])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Updated to Puppeteer 1.6.0\n"),e("ul",[e("li",[t._v("Added "),e("code",[t._v("waitForRequest")]),t._v(" to wait for network request.")]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("waitForResponse")]),t._v(" to wait for network response.")])])]),t._v(" "),e("li",[t._v("Improved TypeScript definitions to support custom steps and page objects. By "),e("strong",[e("a",{attrs:{href:"https://github.com/xt1",target:"_blank",rel:"noopener noreferrer"}},[t._v("xt1"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed XPath detection to accept XPath which starts with "),e("code",[t._v("./")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/BenoitZugmeyer",target:"_blank",rel:"noopener noreferrer"}},[t._v("BenoitZugmeyer"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_1-3-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-1"}},[t._v("#")]),t._v(" 1.3.1")]),t._v(" "),e("ul",[e("li",[t._v("BDD-Gherkin: Fixed running async steps.")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed process hanging for 30 seconds. Page loading timeout default via "),e("code",[t._v("getPageTimeout")]),t._v(" set 0 seconds.")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Improved displaying client-side console messages in debug mode.")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed closing sessions in "),e("code",[t._v("restart:false")]),t._v(" mode for multi-session mode.")]),t._v(" "),e("li",[e("strong",[t._v("[Protractor]")]),t._v(" Fixed "),e("code",[t._v("grabPopupText")]),t._v(" to not throw error popup is not opened.")]),t._v(" "),e("li",[e("strong",[t._v("[Protractor]")]),t._v(" Added info on using 'direct' Protractor driver to helper documentation by "),e("strong",[e("a",{attrs:{href:"https://github.com/xt1",target:"_blank",rel:"noopener noreferrer"}},[t._v("xt1"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" Added a list of all special keys to WebDriverIO helper by "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)]),t._v(" and "),e("strong",[e("a",{attrs:{href:"https://github.com/xt1",target:"_blank",rel:"noopener noreferrer"}},[t._v("xt1"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("Improved TypeScript definitions generator by "),e("strong",[e("a",{attrs:{href:"https://github.com/xt1",target:"_blank",rel:"noopener noreferrer"}},[t._v("xt1"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_1-3-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-3-0"}},[t._v("#")]),t._v(" 1.3.0")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Cucumber-style BDD. Introduced "),e("a",{attrs:{href:"https://codecept.io/bdd",target:"_blank",rel:"noopener noreferrer"}},[t._v("Gherkin support"),e("OutboundLink")],1),t._v(". Thanks to "),e("a",{attrs:{href:"https://github.com/dvins",target:"_blank",rel:"noopener noreferrer"}},[t._v("David Vins"),e("OutboundLink")],1),t._v(" and "),e("a",{attrs:{href:"https://www.omedym.com",target:"_blank",rel:"noopener noreferrer"}},[t._v("Omedym"),e("OutboundLink")],1),t._v(" for sponsoring this feature")]),t._v(".")])]),t._v(" "),e("p",[t._v("Basic feature file:")]),t._v(" "),e("div",{staticClass:"language-gherkin extra-class"},[e("pre",{pre:!0,attrs:{class:"language-gherkin"}},[e("code",[e("span",{pre:!0,attrs:{class:"token feature"}},[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("Feature:")]),e("span",{pre:!0,attrs:{class:"token important"}},[t._v(" Business rules")]),t._v("\n In order to achieve my goals\n As a persona\n I want to be able to interact with a system\n")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token scenario"}},[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("Scenario:")]),e("span",{pre:!0,attrs:{class:"token important"}},[t._v(" do anything in my life")])]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("Given")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token atrule"}},[t._v("I")]),t._v(" need to open Google\n")])])]),e("p",[t._v("Step definition:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("actor")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Given")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I need to open Google'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://google.com'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Run it with "),e("code",[t._v("--features --steps")]),t._v(" flag:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("codeceptjs run --steps --features\n")])])]),e("hr"),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Brekaing Chnage")]),t._v(" "),e("code",[t._v("run")]),t._v(" command now uses relative path + test name to run exactly one test file.")])]),t._v(" "),e("p",[t._v("Previous behavior (removed):")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("codeceptjs run basic_test.js\n")])])]),e("p",[t._v("Current behavior (relative path to config + a test name)")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("codeceptjs run tests/basic_test.js\n")])])]),e("p",[t._v("This change allows using auto-completion when running a specific test.")]),t._v(" "),e("hr"),t._v(" "),e("ul",[e("li",[t._v("Nested steps output enabled for page objects.\n"),e("ul",[e("li",[t._v("to see high-level steps only run tests with "),e("code",[t._v("--steps")]),t._v(" flag.")]),t._v(" "),e("li",[t._v("to see PageObjects implementation run tests with "),e("code",[t._v("--debug")]),t._v(".")])])]),t._v(" "),e("li",[t._v("PageObjects simplified to remove "),e("code",[t._v("_init()")]),t._v(" extra method. Try updated generators and see "),e("a",{attrs:{href:"https://codecept.io/pageobjects/#pageobject",target:"_blank",rel:"noopener noreferrer"}},[t._v("updated guide"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" "),e("a",{attrs:{href:"https://codecept.io/acceptance/#multiple-sessions",target:"_blank",rel:"noopener noreferrer"}},[t._v("Multiple sessions"),e("OutboundLink")],1),t._v(" enabled. Requires Puppeteer >= 1.5")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Stability improvement. Waits for for "),e("code",[t._v("load")]),t._v(" event on page load. This strategy can be changed in config:\n"),e("ul",[e("li",[e("code",[t._v("waitForNavigation")]),t._v(" config option introduced. Possible options: "),e("code",[t._v("load")]),t._v(", "),e("code",[t._v("domcontentloaded")]),t._v(", "),e("code",[t._v("networkidle0")]),t._v(", "),e("code",[t._v("networkidle2")]),t._v(". See "),e("a",{attrs:{href:"https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pagewaitfornavigationoptions",target:"_blank",rel:"noopener noreferrer"}},[t._v("Puppeteer API"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("code",[t._v("getPageTimeout")]),t._v(" config option to set maximum navigation time in milliseconds. Default is 30 seconds.")]),t._v(" "),e("li",[e("code",[t._v("waitForNavigation")]),t._v(" method added. Explicitly waits for navigation to be finished.")])])]),t._v(" "),e("li",[t._v("[WebDriverIO][Protractor][Puppeteer][Nightmare] "),e("strong",[t._v("Possible BC")]),t._v(" "),e("code",[t._v("grabTextFrom")]),t._v(" unified. Return a text for single matched element and an array of texts for multiple elements.")]),t._v(" "),e("li",[t._v("[Puppeteer]Fixed "),e("code",[t._v("resizeWindow")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/sergejkaravajnij",target:"_blank",rel:"noopener noreferrer"}},[t._v("sergejkaravajnij"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[WebDriverIO][Protractor][Puppeteer][Nightmare] "),e("code",[t._v("waitForFunction")]),t._v(" added. Waits for client-side JavaScript function to return true by "),e("strong",[e("a",{attrs:{href:"https://github.com/GREENpoint",target:"_blank",rel:"noopener noreferrer"}},[t._v("GREENpoint"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" "),e("code",[t._v("waitUntil")]),t._v(" deprecated in favor of "),e("code",[t._v("waitForFunction")]),t._v(".")]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("filter")]),t._v(" function to DataTable.")]),t._v(" "),e("li",[t._v("Send non-nested array of files to custom parallel execution chunking by "),e("strong",[e("a",{attrs:{href:"https://github.com/mikecbrant",target:"_blank",rel:"noopener noreferrer"}},[t._v("mikecbrant"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("Fixed invalid output directory path for run-multiple by "),e("strong",[e("a",{attrs:{href:"https://github.com/mikecbrant",target:"_blank",rel:"noopener noreferrer"}},[t._v("mikecbrant"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" "),e("code",[t._v("waitUntil")]),t._v(" timeout accepts time in seconds (as all other wait* functions). Fix by "),e("strong",[e("a",{attrs:{href:"https://github.com/truesrc",target:"_blank",rel:"noopener noreferrer"}},[t._v("truesrc"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Fixed "),e("code",[t._v("grabNumberOfVisibleElements")]),t._v(" to work similarly to "),e("code",[t._v("seeElement")]),t._v(". Thx to "),e("strong",[e("a",{attrs:{href:"https://github.com/stefanschenk",target:"_blank",rel:"noopener noreferrer"}},[t._v("stefanschenk"),e("OutboundLink")],1)]),t._v(" and Jinbo Jinboson.")]),t._v(" "),e("li",[e("strong",[t._v("[Protractor]")]),t._v(" Fixed alert handling error with message 'no such alert' by "),e("strong",[e("a",{attrs:{href:"https://github.com/truesrc",target:"_blank",rel:"noopener noreferrer"}},[t._v("truesrc"),e("OutboundLink")],1)]),t._v(".")])]),t._v(" "),e("h2",{attrs:{id:"_1-2-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-2-1"}},[t._v("#")]),t._v(" 1.2.1")]),t._v(" "),e("ul",[e("li",[t._v("Fixed running "),e("code",[t._v("I.retry()")]),t._v(" on multiple steps.")]),t._v(" "),e("li",[t._v("Fixed parallel execution wih chunks.")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed "),e("code",[t._v("grabNumberOfVisibleElements")]),t._v(" to return "),e("code",[t._v("0")]),t._v(" instead of throwing error if no elements are found.")])]),t._v(" "),e("h2",{attrs:{id:"_1-2-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-2-0"}},[t._v("#")]),t._v(" 1.2.0")]),t._v(" "),e("ul",[e("li",[t._v("[WebDriverIO][Protractor]"),e("a",{attrs:{href:"https://codecept.io/acceptance/#multiple-sessions",target:"_blank",rel:"noopener noreferrer"}},[t._v("Multiple Sessions"),e("OutboundLink")],1),t._v(". Run several browser sessions in one test. Introduced "),e("code",[t._v("session")]),t._v(" command, which opens additional browser window and closes it after a test.")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'run in different browsers'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/hello'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello!'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("session")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/bye'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSee")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Bye'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("a",{attrs:{href:"https://codecept.io/advanced/#parallel-execution",target:"_blank",rel:"noopener noreferrer"}},[t._v("Parallel Execution"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/sveneisenschmidt",target:"_blank",rel:"noopener noreferrer"}},[t._v("sveneisenschmidt"),e("OutboundLink")],1)]),t._v(". Run tests in parallel specifying number of chunks:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"multiple"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"parallel"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// run in 2 processes")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"chunks"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// run all tests in chrome")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"browsers"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"chrome"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("ul",[e("li",[e("a",{attrs:{href:"https://codecept.io/locators",target:"_blank",rel:"noopener noreferrer"}},[t._v("Locator Builder"),e("OutboundLink")],1),t._v(". Write complex locators with simplest API combining CSS and XPath:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// select 'Edit' link inside 2nd row of a table")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("locate")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'//table'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'tr'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("at")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("find")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'a'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("withText")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Edit'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("a",{attrs:{href:"https://codecept.io/advanced/#dynamic-configuration",target:"_blank",rel:"noopener noreferrer"}},[t._v("Dynamic configuration"),e("OutboundLink")],1),t._v(" to update helpers config per test or per suite.")]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("event.test.finished")]),t._v(" which fires synchronously for both failed and passed tests.")]),t._v(" "),e("li",[t._v("[WebDriverIO][Protractor][Nightmare][Puppeteer] Full page screenshots on failure disabled by default. See [issue"),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1600",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1600"),e("OutboundLink")],1),t._v(". You can enabled them with "),e("code",[t._v("fullPageScreenshots: true")]),t._v(", however they may work unstable in Selenium.")]),t._v(" "),e("li",[e("code",[t._v("within")]),t._v(" blocks can return values. See "),e("a",{attrs:{href:"https://codecept.io/basics/#within",target:"_blank",rel:"noopener noreferrer"}},[t._v("updated documentation"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[t._v("Removed doublt call to "),e("code",[t._v("_init")]),t._v(" in helpers. Fixes issue "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/1036",target:"_blank",rel:"noopener noreferrer"}},[t._v("#1036"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Added scenario and feature configuration via fluent API:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'checkout'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("timeout")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("3000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("retry")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user can order in firefox'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// see dynamic configuration")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("config")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'firefox'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("timeout")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("20000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'this test should throw error'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// I.amOnPage")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("throws")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h2",{attrs:{id:"_1-1-8"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-8"}},[t._v("#")]),t._v(" 1.1.8")]),t._v(" "),e("ul",[e("li",[t._v("Fixed generating TypeScript definitions with "),e("code",[t._v("codeceptjs def")]),t._v(".")]),t._v(" "),e("li",[t._v('Added Chinese translation ("zh-CN" and "zh-TW") by '),e("strong",[e("a",{attrs:{href:"https://github.com/TechQuery",target:"_blank",rel:"noopener noreferrer"}},[t._v("TechQuery"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("Fixed running tests from a different folder specified by "),e("code",[t._v("-c")]),t._v(" option.")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Added support for hash handling in URL by "),e("strong",[e("a",{attrs:{href:"https://github.com/gavoja",target:"_blank",rel:"noopener noreferrer"}},[t._v("gavoja"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed setting viewport size by "),e("strong",[e("a",{attrs:{href:"https://github.com/gavoja",target:"_blank",rel:"noopener noreferrer"}},[t._v("gavoja"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/GoogleChrome/puppeteer/issues/1183",target:"_blank",rel:"noopener noreferrer"}},[t._v("Puppeteer issue"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_1-1-7"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-7"}},[t._v("#")]),t._v(" 1.1.7")]),t._v(" "),e("ul",[e("li",[t._v("Docker Image updateed. "),e("a",{attrs:{href:"https://codecept.io/docker/",target:"_blank",rel:"noopener noreferrer"}},[t._v("See updated reference"),e("OutboundLink")],1),t._v(":\n"),e("ul",[e("li",[t._v("codeceptjs package is mounted as "),e("code",[t._v("/codecept")]),t._v(" insde container")]),t._v(" "),e("li",[t._v("tests directory is expected to be mounted as "),e("code",[t._v("/tests")])]),t._v(" "),e("li",[e("code",[t._v("codeceptjs")]),t._v(" global runner added (symlink to "),e("code",[t._v("/codecept/bin/codecept.js")]),t._v(")")])])]),t._v(" "),e("li",[e("strong",[t._v("[Protractor]")]),t._v(" Functions added by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)]),t._v(":\n"),e("ul",[e("li",[e("code",[t._v("_locateCheckable (only available from other helpers)")])]),t._v(" "),e("li",[e("code",[t._v("_locateClickable (only available from other helpers)")])]),t._v(" "),e("li",[e("code",[t._v("_locateFields (only available from other helpers)")])]),t._v(" "),e("li",[e("code",[t._v("acceptPopup")])]),t._v(" "),e("li",[e("code",[t._v("cancelPopup")])]),t._v(" "),e("li",[e("code",[t._v("dragAndDrop")])]),t._v(" "),e("li",[e("code",[t._v("grabBrowserLogs")])]),t._v(" "),e("li",[e("code",[t._v("grabCssPropertyFrom")])]),t._v(" "),e("li",[e("code",[t._v("grabHTMLFrom")])]),t._v(" "),e("li",[e("code",[t._v("grabNumberOfVisibleElements")])]),t._v(" "),e("li",[e("code",[t._v("grabPageScrollPosition (new)")])]),t._v(" "),e("li",[e("code",[t._v("rightClick")])]),t._v(" "),e("li",[e("code",[t._v("scrollPageToBottom")])]),t._v(" "),e("li",[e("code",[t._v("scrollPageToTop")])]),t._v(" "),e("li",[e("code",[t._v("scrollTo")])]),t._v(" "),e("li",[e("code",[t._v("seeAttributesOnElements")])]),t._v(" "),e("li",[e("code",[t._v("seeCssPropertiesOnElements")])]),t._v(" "),e("li",[e("code",[t._v("seeInPopup")])]),t._v(" "),e("li",[e("code",[t._v("seeNumberOfVisibleElements")])]),t._v(" "),e("li",[e("code",[t._v("switchTo")])]),t._v(" "),e("li",[e("code",[t._v("waitForEnabled")])]),t._v(" "),e("li",[e("code",[t._v("waitForValue")])]),t._v(" "),e("li",[e("code",[t._v("waitInUrl")])]),t._v(" "),e("li",[e("code",[t._v("waitNumberOfVisibleElements")])]),t._v(" "),e("li",[e("code",[t._v("waitToHide")])]),t._v(" "),e("li",[e("code",[t._v("waitUntil")])]),t._v(" "),e("li",[e("code",[t._v("waitUrlEquals")])])])]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" added:\n"),e("ul",[e("li",[e("code",[t._v("grabPageScrollPosition")]),t._v(" (new)")]),t._v(" "),e("li",[e("code",[t._v("seeNumberOfVisibleElements")])]),t._v(" "),e("li",[e("code",[t._v("waitToHide")])])])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" added:\n"),e("ul",[e("li",[e("code",[t._v("grabPageScrollPosition")]),t._v(" (new)")])])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(' added"\n'),e("ul",[e("li",[e("code",[t._v("grabPageScrollPosition")]),t._v(" (new)")])])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixed running wait* functions without setting "),e("code",[t._v("sec")]),t._v(" parameter.")]),t._v(" "),e("li",[t._v("[Puppeteer][Protractor] Fixed bug with I.click when using an object selector with the xpath property. By "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[WebDriverIO][Protractor][Nightmare][Puppeteer] Fixed I.switchTo(0) and I.scrollTo(100, 100) api inconsistencies between helpers.")]),t._v(" "),e("li",[e("strong",[t._v("[Protractor]")]),t._v(" Fixing bug when "),e("code",[t._v("seeAttributesOnElements")]),t._v(" and "),e("code",[t._v("seeCssPropertiesOnElement")]),t._v(" were incorrectly passing when the attributes/properties did not match by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" Use inbuilt dragAndDrop function (still doesn't work in Firefox). By "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Support for Nightmare 3.0")]),t._v(" "),e("li",[t._v("Enable glob patterns in "),e("code",[t._v("config.test")]),t._v(" / "),e("code",[t._v("Codecept.loadTests")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/sveneisenschmidt",target:"_blank",rel:"noopener noreferrer"}},[t._v("sveneisenschmidt"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Enable overriding of "),e("code",[t._v("config.tests")]),t._v(" for "),e("code",[t._v("run-multiple")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/sveneisenschmidt",target:"_blank",rel:"noopener noreferrer"}},[t._v("sveneisenschmidt"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_1-1-6"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-6"}},[t._v("#")]),t._v(" 1.1.6")]),t._v(" "),e("ul",[e("li",[t._v("Added support for "),e("code",[t._v("async I =>")]),t._v(" functions syntax in Scenario by "),e("strong",[e("a",{attrs:{href:"https://github.com/APshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APshenkin"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[WebDriverIO][Protractor][Puppeteer][Nightmare] "),e("code",[t._v("waitForInvisible")]),t._v(" waits for element to hide or to be removed from page. By "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[Protractor][Puppeteer][Nightmare] Added "),e("code",[t._v("grabCurrentUrl")]),t._v(" function. By "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" "),e("code",[t._v("grabBrowserUrl")]),t._v(" deprecated in favor of "),e("code",[t._v("grabCurrentUrl")]),t._v(" to unify the API.")]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Improved element visibility detection by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Fixing function calls when clearing the cookies and localstorage. By "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Added "),e("code",[t._v("waitForEnabled")]),t._v(", "),e("code",[t._v("waitForValue")]),t._v(" and "),e("code",[t._v("waitNumberOfVisibleElements")]),t._v(" methods by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" Fixed "),e("code",[t._v("grabNumberOfVisibleElements")]),t._v(" to return 0 when no visible elements are on page. By "),e("strong",[e("a",{attrs:{href:"https://github.com/michaltrunek",target:"_blank",rel:"noopener noreferrer"}},[t._v("michaltrunek"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Helpers API improvements (by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)]),t._v(")\n"),e("ul",[e("li",[e("code",[t._v("_passed")]),t._v(" hook runs after a test passed successfully")]),t._v(" "),e("li",[e("code",[t._v("_failed")]),t._v(" hook runs on a failed test")])])]),t._v(" "),e("li",[t._v("Hooks API. New events added by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)]),t._v(":\n"),e("ul",[e("li",[e("code",[t._v("event.all.before")]),t._v(" - executed before all tests")]),t._v(" "),e("li",[e("code",[t._v("event.all.after")]),t._v(" - executed after all tests")]),t._v(" "),e("li",[e("code",[t._v("event.multiple.before")]),t._v(" - executed before all processes in run-multiple")]),t._v(" "),e("li",[e("code",[t._v("event.multiple.after")]),t._v(" - executed after all processes in run-multiple")])])]),t._v(" "),e("li",[t._v("Multiple execution")]),t._v(" "),e("li",[t._v("Allow "),e("code",[t._v("AfterSuite")]),t._v(" and "),e("code",[t._v("After")]),t._v(" test hooks to be defined after the first Scenario. By "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Prevent "),e("code",[t._v("I.amOnpage")]),t._v(" navigation if the browser is already at the given url")]),t._v(" "),e("li",[t._v("Multiple-Run: Added new "),e("code",[t._v("bootstrapAll")]),t._v(" and "),e("code",[t._v("teardownAll")]),t._v(" hooks to be executed before and after all processes")]),t._v(" "),e("li",[e("code",[t._v("codeceptjs def")]),t._v(" command accepts "),e("code",[t._v("--config")]),t._v(" option. By "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_1-1-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-5"}},[t._v("#")]),t._v(" 1.1.5")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(' Rerun steps failed due to "Cannot find context with specified id" Error.')]),t._v(" "),e("li",[t._v("Added syntax to retry a single step:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// retry action once on failure")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("retry")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// retry action 3 times on failure")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("retry")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// retry action 3 times waiting for 0.1 second before next try")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("retry")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("retries")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("minTimeout")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// retry action 3 times waiting no more than 3 seconds for last retry")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("retry")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("retries")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("maxTimeout")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("3000")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// retry 2 times if error with message 'Node not visible' happens")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("retry")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("retries")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("when")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("err")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" err"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("message "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("===")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Node not visible'")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#user'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("code",[t._v("Scenario().injectDependencies")]),t._v(" added to dynamically add objects into DI container by "),e("strong",[e("a",{attrs:{href:"https://github.com/Apshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("Apshenkin"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://codecept.io/pageobjects/#dependency-injection",target:"_blank",rel:"noopener noreferrer"}},[t._v("Dependency Injection section in PageObjects"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[t._v("Fixed using async/await functions inside "),e("code",[t._v("within")])]),t._v(" "),e("li",[t._v("[WebDriverIO][Protractor][Puppeteer][Nightmare] "),e("strong",[e("code",[t._v("waitUntilExists")]),t._v(" deprecated")]),t._v(" in favor of "),e("code",[t._v("waitForElement")])]),t._v(" "),e("li",[t._v("[WebDriverIO][Protractor] "),e("strong",[e("code",[t._v("waitForStalenessOf")]),t._v(" deprecated")]),t._v(" in favor of "),e("code",[t._v("waitForDetached")])]),t._v(" "),e("li",[t._v("[WebDriverIO][Protractor][Puppeteer][Nightmare] "),e("code",[t._v("waitForDetached")]),t._v(" added")]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Added "),e("code",[t._v("I.seeNumberOfElements()")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/pmoncadaisla",target:"_blank",rel:"noopener noreferrer"}},[t._v("pmoncadaisla"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Load blank page when starting nightmare so that the .evaluate function will work if _failed/saveScreenshot is triggered by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed using plain arrays for data driven tests by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Use default tab instead of opening a new tab when starting the browser by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Added "),e("code",[t._v("grabNumberOfTabs")]),t._v(" function by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Add ability to set user-agent by "),e("strong",[e("a",{attrs:{href:"https://github.com/abidhahmed",target:"_blank",rel:"noopener noreferrer"}},[t._v("abidhahmed"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Add keepCookies and keepBrowserState "),e("strong",[e("a",{attrs:{href:"https://github.com/abidhahmed",target:"_blank",rel:"noopener noreferrer"}},[t._v("abidhahmed"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Clear value attribute instead of innerhtml for TEXTAREA by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[REST]")]),t._v(" fixed sending string payload by "),e("strong",[e("a",{attrs:{href:"https://github.com/michaltrunek",target:"_blank",rel:"noopener noreferrer"}},[t._v("michaltrunek"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed unhandled rejection in async/await tests by "),e("strong",[e("a",{attrs:{href:"https://github.com/APshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APshenkin"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_1-1-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-4"}},[t._v("#")]),t._v(" 1.1.4")]),t._v(" "),e("ul",[e("li",[t._v("Removed "),e("code",[t._v("yarn")]),t._v(" call in package.json")]),t._v(" "),e("li",[t._v("Fixed "),e("code",[t._v("console.log")]),t._v(" in Puppeteer by "),e("strong",[e("a",{attrs:{href:"https://github.com/othree",target:"_blank",rel:"noopener noreferrer"}},[t._v("othree"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Appium]")]),t._v(" "),e("code",[t._v("runOnAndroid")]),t._v(" and "),e("code",[t._v("runOnIOS")]),t._v(" can receive a function to check capabilities dynamically:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("runOnAndroid")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("caps")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" caps"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("platformVersion "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("7")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// run code only on Android 7+")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h2",{attrs:{id:"_1-1-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-3"}},[t._v("#")]),t._v(" 1.1.3")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" +25 Functions added by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[e("code",[t._v("_locateCheckable")])]),t._v(" "),e("li",[e("code",[t._v("_locateClickable")])]),t._v(" "),e("li",[e("code",[t._v("_locateFields")])]),t._v(" "),e("li",[e("code",[t._v("closeOtherTabs")])]),t._v(" "),e("li",[e("code",[t._v("dragAndDrop")])]),t._v(" "),e("li",[e("code",[t._v("grabBrowserLogs")])]),t._v(" "),e("li",[e("code",[t._v("grabCssPropertyFrom")])]),t._v(" "),e("li",[e("code",[t._v("grabHTMLFrom")])]),t._v(" "),e("li",[e("code",[t._v("grabNumberOfVisibleElements")])]),t._v(" "),e("li",[e("code",[t._v("grabSource")])]),t._v(" "),e("li",[e("code",[t._v("rightClick")])]),t._v(" "),e("li",[e("code",[t._v("scrollPageToBottom")])]),t._v(" "),e("li",[e("code",[t._v("scrollPageToTop")])]),t._v(" "),e("li",[e("code",[t._v("scrollTo")])]),t._v(" "),e("li",[e("code",[t._v("seeAttributesOnElements")])]),t._v(" "),e("li",[e("code",[t._v("seeCssPropertiesOnElements")])]),t._v(" "),e("li",[e("code",[t._v("seeInField")])]),t._v(" "),e("li",[e("code",[t._v("seeNumberOfElements")])]),t._v(" "),e("li",[e("code",[t._v("seeNumberOfVisibleElements")])]),t._v(" "),e("li",[e("code",[t._v("seeTextEquals")])]),t._v(" "),e("li",[e("code",[t._v("seeTitleEquals")])]),t._v(" "),e("li",[e("code",[t._v("switchTo")])]),t._v(" "),e("li",[e("code",[t._v("waitForInvisible")])]),t._v(" "),e("li",[e("code",[t._v("waitInUrl")])]),t._v(" "),e("li",[e("code",[t._v("waitUrlEquals")])])])]),t._v(" "),e("li",[e("strong",[t._v("[Protractor]")]),t._v(" +8 functions added by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[e("code",[t._v("closeCurrentTab")])]),t._v(" "),e("li",[e("code",[t._v("grabSource")])]),t._v(" "),e("li",[e("code",[t._v("openNewTab")])]),t._v(" "),e("li",[e("code",[t._v("seeNumberOfElements")])]),t._v(" "),e("li",[e("code",[t._v("seeTextEquals")])]),t._v(" "),e("li",[e("code",[t._v("seeTitleEquals")])]),t._v(" "),e("li",[e("code",[t._v("switchToNextTab")])]),t._v(" "),e("li",[e("code",[t._v("switchToPreviousTab")])])])]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" "),e("code",[t._v("waitForInvisible")]),t._v(" added by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Printing console.log information in debug mode.")]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Integrated with "),e("code",[t._v("nightmare-har-plugin")]),t._v(" by mingfang. Added "),e("code",[t._v("enableHAR")]),t._v(" option. Added HAR functions:\n"),e("ul",[e("li",[e("code",[t._v("grabHAR")])]),t._v(" "),e("li",[e("code",[t._v("saveHAR")])]),t._v(" "),e("li",[e("code",[t._v("resetHAR")])])])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" Fixed execution stability for parallel requests with Chromedriver")]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" Fixed resizeWindow when resizing to 'maximize' by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" Fixing resizing window to full screen when taking a screenshot by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_1-1-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-2"}},[t._v("#")]),t._v(" 1.1.2")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Upgraded to Puppeteer 1.0")]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("grep")]),t._v(" option to config to set default matching pattern for tests.")]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" Added "),e("code",[t._v("acceptPopup")]),t._v(", "),e("code",[t._v("cancelPopup")]),t._v(", "),e("code",[t._v("seeInPopup")]),t._v(" and "),e("code",[t._v("grabPopupText")]),t._v(" functions by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Puppeteer]")]),t._v(" "),e("code",[t._v("within")]),t._v(" iframe and nested iframe support added by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[REST]")]),t._v(' Added support for JSON objects since payload (as a JSON) was automatically converted into "URL query" type of parameter by '),e("strong",[e("a",{attrs:{href:"https://github.com/Kalostrinho",target:"_blank",rel:"noopener noreferrer"}},[t._v("Kalostrinho"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[REST]")]),t._v(" Added "),e("code",[t._v("resetRequestHeaders")]),t._v(" method by "),e("strong",[e("a",{attrs:{href:"https://github.com/Kalostrinho",target:"_blank",rel:"noopener noreferrer"}},[t._v("Kalostrinho"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[REST]")]),t._v(" Added "),e("code",[t._v("followRedirect")]),t._v(" option and "),e("code",[t._v("amFollowingRequestRedirects")]),t._v("/"),e("code",[t._v("amNotFollowingRequestRedirects")]),t._v(" methods by "),e("strong",[e("a",{attrs:{href:"https://github.com/Kalostrinho",target:"_blank",rel:"noopener noreferrer"}},[t._v("Kalostrinho"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" "),e("code",[t._v("uncheckOption")]),t._v(" implemented by "),e("strong",[e("a",{attrs:{href:"https://github.com/brunobg",target:"_blank",rel:"noopener noreferrer"}},[t._v("brunobg"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" Added "),e("code",[t._v("grabBrowserUrl")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Kalostrinho",target:"_blank",rel:"noopener noreferrer"}},[t._v("Kalostrinho"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Add ability to require helpers from node_modules by "),e("strong",[e("a",{attrs:{href:"https://github.com/APshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APshenkin"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("--profile")]),t._v(" option to "),e("code",[t._v("run-multiple")]),t._v(" command by "),e("strong",[e("a",{attrs:{href:"https://github.com/jamie-beck",target:"_blank",rel:"noopener noreferrer"}},[t._v("jamie-beck"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Custom output name for multiple browser run by "),e("strong",[e("a",{attrs:{href:"https://github.com/tfiwm",target:"_blank",rel:"noopener noreferrer"}},[t._v("tfiwm"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed passing data to scenarios by "),e("strong",[e("a",{attrs:{href:"https://github.com/KennyRules",target:"_blank",rel:"noopener noreferrer"}},[t._v("KennyRules"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_1-1-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-1"}},[t._v("#")]),t._v(" 1.1.1")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" fixed "),e("code",[t._v("waitForInvisible")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/Kporal",target:"_blank",rel:"noopener noreferrer"}},[t._v("Kporal"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_1-1-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-1-0"}},[t._v("#")]),t._v(" 1.1.0")]),t._v(" "),e("p",[t._v("Major update to CodeceptJS. "),e("strong",[t._v("NodeJS v 8.9.1")]),t._v(" is now minimal Node version required.\nThis brings native async-await support to CodeceptJS. It is recommended to start using await for tests instead of generators:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/page'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" url "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabTextFrom")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.nextPage'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("url"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("Thanks to "),e("a",{attrs:{href:"https://github.com/apshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("@Apshenkin"),e("OutboundLink")],1),t._v(" for implementation. Also, most helpers were refactored to use async-await. This made our code simpler. We hope that this encourages more users to send pull requests!")]),t._v(" "),e("p",[t._v("We also introduced strict ESLint policies for our codebase. Thanks to "),e("a",{attrs:{href:"https://github.com/galkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("@Galkin"),e("OutboundLink")],1),t._v(" for that.")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Puppeteer] Helper introduced")]),t._v(". "),e("a",{attrs:{href:"http://codecept.io/puppeteer/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Learn how to run tests headlessly with Google Chrome's Puppeteer"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[SeleniumWebdriver]")]),t._v(" Helper is deprecated, it is recommended to use Protractor with config option "),e("code",[t._v("angular: false")]),t._v(" instead.")]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" nested iframe support in the within block by "),e("strong",[e("a",{attrs:{href:"https://github.com/reubenmiller",target:"_blank",rel:"noopener noreferrer"}},[t._v("reubenmiller"),e("OutboundLink")],1)]),t._v(". Example:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token function"}},[t._v("within")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("frame")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#wrapperId'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'[name=content]'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Sign in!'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Email Address'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Nested Iframe test'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSee")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Email Address'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" Support for "),e("code",[t._v("~")]),t._v(" locator to find elements by "),e("code",[t._v("aria-label")]),t._v(". This behavior is similar as it is in Appium and helps testing cross-platform React apps. Example:")])]),t._v(" "),e("div",{staticClass:"language-html extra-class"},[e("pre",{pre:!0,attrs:{class:"language-html"}},[e("code",[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("<")]),t._v("Text")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token attr-name"}},[t._v("accessibilityLabel")]),e("span",{pre:!0,attrs:{class:"token attr-value"}},[e("span",{pre:!0,attrs:{class:"token punctuation attr-equals"}},[t._v("=")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')]),t._v("foobar"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v('"')])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(">")])]),t._v("\n CodeceptJS is awesome\n"),e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token tag"}},[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("")])]),t._v("\n")])])]),e("p",[t._v("↑ This element can be located with "),e("code",[t._v("~foobar")]),t._v(" in WebDriverIO and Appium helpers. Thanks to "),e("strong",[e("a",{attrs:{href:"https://github.com/flyskywhy",target:"_blank",rel:"noopener noreferrer"}},[t._v("flyskywhy"),e("OutboundLink")],1)])]),t._v(" "),e("ul",[e("li",[t._v("Allow providing arbitrary objects in config includes by "),e("strong",[e("a",{attrs:{href:"https://github.com/rlewan",target:"_blank",rel:"noopener noreferrer"}},[t._v("rlewan"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[REST]")]),t._v(" Prevent from mutating default headers by "),e("strong",[e("a",{attrs:{href:"https://github.com/alexashley",target:"_blank",rel:"noopener noreferrer"}},[t._v("alexashley"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/789",target:"_blank",rel:"noopener noreferrer"}},[t._v("#789"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("strong",[t._v("[REST]")]),t._v(" Fixed sending empty helpers with "),e("code",[t._v("haveRequestHeaders")]),t._v(" in "),e("code",[t._v("sendPostRequest")]),t._v(". By "),e("strong",[e("a",{attrs:{href:"https://github.com/petrisorionel",target:"_blank",rel:"noopener noreferrer"}},[t._v("petrisorionel"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed displaying undefined args in output by "),e("strong",[e("a",{attrs:{href:"https://github.com/APshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APshenkin"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed NaN instead of seconds in output by "),e("strong",[e("a",{attrs:{href:"https://github.com/APshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APshenkin"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Add browser name to report file for "),e("code",[t._v("multiple-run")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/trollr",target:"_blank",rel:"noopener noreferrer"}},[t._v("trollr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Mocha updated to 4.x")])]),t._v(" "),e("h2",{attrs:{id:"_1-0-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-0-3"}},[t._v("#")]),t._v(" 1.0.3")]),t._v(" "),e("ul",[e("li",[t._v("[WebDriverIO][Protractor][Nightmare] method "),e("code",[t._v("waitUntilExists")]),t._v(" implemented by "),e("strong",[e("a",{attrs:{href:"https://github.com/sabau",target:"_blank",rel:"noopener noreferrer"}},[t._v("sabau"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Absolute path can be set for "),e("code",[t._v("output")]),t._v(" dir by "),e("strong",[e("a",{attrs:{href:"https://github.com/APshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APshenkin"),e("OutboundLink")],1)]),t._v(". Fix "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/571",target:"_blank",rel:"noopener noreferrer"}},[t._v("#571"),e("OutboundLink")],1),t._v("* Data table rows can be ignored by using "),e("code",[t._v("xadd")]),t._v(". By "),e("strong",[e("a",{attrs:{href:"https://github.com/APhenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APhenkin"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("Data(table).only.Scenario")]),t._v(" to give ability to launch only Data tests. By "),e("strong",[e("a",{attrs:{href:"https://github.com/APhenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APhenkin"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Implemented "),e("code",[t._v("ElementNotFound")]),t._v(" error by "),e("strong",[e("a",{attrs:{href:"https://github.com/BorisOsipov",target:"_blank",rel:"noopener noreferrer"}},[t._v("BorisOsipov"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("Added TypeScript compiler / configs to check the JavaScript by "),e("strong",[e("a",{attrs:{href:"https://github.com/KennyRules",target:"_blank",rel:"noopener noreferrer"}},[t._v("KennyRules"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" fix executeScript return value by "),e("strong",[e("a",{attrs:{href:"https://github.com/jploskonka",target:"_blank",rel:"noopener noreferrer"}},[t._v("jploskonka"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" fixed: err.indexOf not a function when waitForText times out in nightmare by "),e("strong",[e("a",{attrs:{href:"https://github.com/joeypedicini92",target:"_blank",rel:"noopener noreferrer"}},[t._v("joeypedicini92"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed: Retries not working when using .only. By "),e("strong",[e("a",{attrs:{href:"https://github.com/APhenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APhenkin"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_1-0-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-0-2"}},[t._v("#")]),t._v(" 1.0.2")]),t._v(" "),e("ul",[e("li",[t._v("Introduced generators support in scenario hooks for "),e("code",[t._v("BeforeSuite")]),t._v("/"),e("code",[t._v("Before")]),t._v("/"),e("code",[t._v("AfterSuite")]),t._v("/"),e("code",[t._v("After")])]),t._v(" "),e("li",[e("strong",[t._v("[ApiDataFactory]")]),t._v(" Fixed loading helper; "),e("code",[t._v("requireg")]),t._v(" package included.")]),t._v(" "),e("li",[t._v("Fix "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/485",target:"_blank",rel:"noopener noreferrer"}},[t._v("#485"),e("OutboundLink")],1),e("code",[t._v("run-multiple")]),t._v(": the first browser-resolution combination was be used in all configurations")]),t._v(" "),e("li",[t._v("Fixed unique test names:\n"),e("ul",[e("li",[t._v("Fixed "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/447",target:"_blank",rel:"noopener noreferrer"}},[t._v("#447"),e("OutboundLink")],1),t._v(" tests failed silently if they have the same name as other tests.")]),t._v(" "),e("li",[t._v("Use uuid in screenshot names when "),e("code",[t._v("uniqueScreenshotNames: true")])])])]),t._v(" "),e("li",[e("strong",[t._v("[Protractor]")]),t._v(" Fixed testing non-angular application. "),e("code",[t._v("amOutsideAngularApp")]),t._v(" is executed before each step. Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/458",target:"_blank",rel:"noopener noreferrer"}},[t._v("#458"),e("OutboundLink")],1),t._v("* Added output for steps in hooks when they fail")])]),t._v(" "),e("h2",{attrs:{id:"_1-0-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-0-1"}},[t._v("#")]),t._v(" 1.0.1")]),t._v(" "),e("ul",[e("li",[t._v("Reporters improvements:\n"),e("ul",[e("li",[t._v("Allows to execute "),e("a",{attrs:{href:"http://codecept.io/advanced/#Multi-Reports",target:"_blank",rel:"noopener noreferrer"}},[t._v("multiple reporters"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Added "),e("a",{attrs:{href:"http://codecept.io/helpers/Mochawesome/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mochawesome"),e("OutboundLink")],1),t._v(" helper")]),t._v(" "),e("li",[e("code",[t._v("addMochawesomeContext")]),t._v(" method to add custom data to mochawesome reports")]),t._v(" "),e("li",[t._v("Fixed Mochawesome context for failed screenshots.")])])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" improved click on context to match clickable element with a text inside. Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/647",target:"_blank",rel:"noopener noreferrer"}},[t._v("#647"),e("OutboundLink")],1),t._v("* "),e("strong",[t._v("[Nightmare]")]),t._v(" Added "),e("code",[t._v("refresh")]),t._v(" function by "),e("strong",[e("a",{attrs:{href:"https://github.com/awhanks",target:"_blank",rel:"noopener noreferrer"}},[t._v("awhanks"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("fixed "),e("code",[t._v("Unhandled promise rejection (rejection id: 1): Error: Unknown wait type: pageLoad")])]),t._v(" "),e("li",[t._v("support for tests with retries in html report")]),t._v(" "),e("li",[t._v("be sure that change window size and timeouts completes before test")]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Fixed "),e("code",[t._v('[Wrapped Error] "codeceptjs is not defined"')]),t._v("; Reinjectiing client scripts to a webpage on changes.")]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Added more detailed error messages for "),e("code",[t._v("Wait*")]),t._v(" methods")]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Fixed adding screenshots to Mochawesome")]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Fix unique screenshots names in Nightmare")]),t._v(" "),e("li",[t._v("Fixed CodeceptJS work with hooks in helpers to finish codeceptJS correctly if errors appears in helpers hooks")]),t._v(" "),e("li",[t._v("Create a new session for next test If selenium grid error received")]),t._v(" "),e("li",[t._v("Create screenshots for failed hooks from a Feature file")]),t._v(" "),e("li",[t._v("Fixed "),e("code",[t._v("retries")]),t._v(" option")])]),t._v(" "),e("h2",{attrs:{id:"_1-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_1-0"}},[t._v("#")]),t._v(" 1.0")]),t._v(" "),e("p",[t._v("CodeceptJS hits first stable release. CodeceptJS provides a unified API for "),e("a",{attrs:{href:"http://codecept.io/acceptance/",target:"_blank",rel:"noopener noreferrer"}},[t._v("web testing for Webdriverio"),e("OutboundLink")],1),t._v(", "),e("a",{attrs:{href:"http://codecept.io/angular/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Protractor"),e("OutboundLink")],1),t._v(", and "),e("a",{attrs:{href:"http://codecept.io/nightmare/",target:"_blank",rel:"noopener noreferrer"}},[t._v("NightmareJS"),e("OutboundLink")],1),t._v(". Since 1.0 you can also "),e("strong",[t._v("test mobile applications")]),t._v(" in the similar manner with Appium.")]),t._v(" "),e("p",[t._v("Sample test:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeAppIsInstalled")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"io.super.app"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~startUserRegistrationCD'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~email of the customer'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Nothing special'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert@codecept.io'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~email of the customer'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("clearField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~email of the customer'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSee")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Nothing special'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~email of the customer'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Read "),e("a",{attrs:{href:"http://codecept.io/mobile",target:"_blank",rel:"noopener noreferrer"}},[t._v("the Mobile Testing guide"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[t._v("Discover "),e("a",{attrs:{href:"http://codecept.io/helpers/Appium/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Appium Helper"),e("OutboundLink")],1)])]),t._v(" "),e("hr"),t._v(" "),e("p",[t._v("We also introduced two new "),e("strong",[t._v("helpers for data management")]),t._v(".\nUsing them you can easily prepare and cleanup data for your tests using public REST API.")]),t._v(" "),e("p",[t._v("Sample test")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a user using data factories and REST API")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("have")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("password")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'123456'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// use it to login")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/login'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'login'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'123456'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello, davert'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// user will be removed after the test")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Read "),e("a",{attrs:{href:"http://codecept.io/data",target:"_blank",rel:"noopener noreferrer"}},[t._v("Data Management guide"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/REST",target:"_blank",rel:"noopener noreferrer"}},[t._v("REST Helper"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/ApiDataFactory/",target:"_blank",rel:"noopener noreferrer"}},[t._v("ApiDataFactory"),e("OutboundLink")],1)])]),t._v(" "),e("hr"),t._v(" "),e("p",[t._v("Next notable feature is "),e("strong",[e("a",{attrs:{href:"http://codecept.io/acceptance/#smartwait",target:"_blank",rel:"noopener noreferrer"}},[t._v("SmartWait"),e("OutboundLink")],1)]),t._v(" for WebDriverIO, Protractor, SeleniumWebdriver. When "),e("code",[t._v("smartwait")]),t._v(" option is set, script will wait for extra milliseconds to locate an element before failing. This feature uses implicit waits of Selenium but turns them on only in applicable pieces. For instance, implicit waits are enabled for "),e("code",[t._v("seeElement")]),t._v(" but disabled for "),e("code",[t._v("dontSeeElement")])]),t._v(" "),e("ul",[e("li",[t._v("Read more about "),e("a",{attrs:{href:"http://codecept.io/acceptance/#smartwait",target:"_blank",rel:"noopener noreferrer"}},[t._v("SmartWait"),e("OutboundLink")],1)])]),t._v(" "),e("h5",{attrs:{id:"changelog"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#changelog"}},[t._v("#")]),t._v(" Changelog")]),t._v(" "),e("ul",[e("li",[t._v("Minimal NodeJS version is 6.11.1 LTS")]),t._v(" "),e("li",[t._v("Use "),e("code",[t._v("within")]),t._v(" command with generators.")]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/advanced/#data-driven-tests",target:"_blank",rel:"noopener noreferrer"}},[t._v("Data Driven Tests"),e("OutboundLink")],1),t._v(" introduced.")]),t._v(" "),e("li",[t._v("Print execution time per step in "),e("code",[t._v("--debug")]),t._v(" mode. "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/591",target:"_blank",rel:"noopener noreferrer"}},[t._v("#591"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/APshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APshenkin"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[WebDriverIO][Protractor][Nightmare] Added "),e("code",[t._v("disableScreenshots")]),t._v(" option to disable screenshots on fail by "),e("strong",[e("a",{attrs:{href:"https://github.com/Apshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("Apshenkin"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[WebDriverIO][Protractor][Nightmare] Added "),e("code",[t._v("uniqueScreenshotNames")]),t._v(" option to generate unique names for screenshots on failure by "),e("strong",[e("a",{attrs:{href:"https://github.com/Apshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("Apshenkin"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[WebDriverIO][Nightmare] Fixed click on context; "),e("code",[t._v("click('text', '#el')")]),t._v(" will throw exception if text is not found inside "),e("code",[t._v("#el")]),t._v(".")]),t._v(" "),e("li",[t._v("[WebDriverIO][Protractor][SeleniumWebdriver] "),e("a",{attrs:{href:"http://codecept.io/acceptance/#smartwait",target:"_blank",rel:"noopener noreferrer"}},[t._v("SmartWait introduced"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[t._v("[WebDriverIO][Protractor][Nightmare]Fixed "),e("code",[t._v("saveScreenshot")]),t._v(" for PhantomJS, "),e("code",[t._v("fullPageScreenshots")]),t._v(" option introduced by "),e("strong",[e("a",{attrs:{href:"https://github.com/HughZurname",target:"_blank",rel:"noopener noreferrer"}},[t._v("HughZurname"),e("OutboundLink")],1)]),t._v(" "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/549",target:"_blank",rel:"noopener noreferrer"}},[t._v("#549"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("strong",[t._v("[Appium]")]),t._v(" helper introduced by "),e("strong",[e("a",{attrs:{href:"https://github.com/APshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APshenkin"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[REST]")]),t._v(" helper introduced by "),e("strong",[e("a",{attrs:{href:"https://github.com/atrevino",target:"_blank",rel:"noopener noreferrer"}},[t._v("atrevino"),e("OutboundLink")],1)]),t._v(" in "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/504",target:"_blank",rel:"noopener noreferrer"}},[t._v("#504"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v('[WebDriverIO][SeleniumWebdriver] Fixed "windowSize": "maximize" for Chrome 59+ version '),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/560",target:"_blank",rel:"noopener noreferrer"}},[t._v("#560"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/APshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APshenkin"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Fixed restarting by "),e("strong",[e("a",{attrs:{href:"https://github.com/APshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APshenkin"),e("OutboundLink")],1)]),t._v(" "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/581",target:"_blank",rel:"noopener noreferrer"}},[t._v("#581"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" Methods added by "),e("strong",[e("a",{attrs:{href:"https://github.com/APshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APshenkin"),e("OutboundLink")],1)]),t._v(":\n"),e("ul",[e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/WebDriverIO/#grabcsspropertyfrom",target:"_blank",rel:"noopener noreferrer"}},[t._v("grabCssPropertyFrom"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/WebDriverIO/#seetitleequals",target:"_blank",rel:"noopener noreferrer"}},[t._v("seeTitleEquals"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/WebDriverIO/#seetextequals",target:"_blank",rel:"noopener noreferrer"}},[t._v("seeTextEquals"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/WebDriverIO/#seecsspropertiesonelements",target:"_blank",rel:"noopener noreferrer"}},[t._v("seeCssPropertiesOnElements"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/WebDriverIO/#seeattributesonelements",target:"_blank",rel:"noopener noreferrer"}},[t._v("seeAttributesOnElements"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/WebDriverIO/#grabnumberofvisibleelements",target:"_blank",rel:"noopener noreferrer"}},[t._v("grabNumberOfVisibleElements"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/WebDriverIO/#waitinurl",target:"_blank",rel:"noopener noreferrer"}},[t._v("waitInUrl"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/WebDriverIO/#waiturlequals",target:"_blank",rel:"noopener noreferrer"}},[t._v("waitUrlEquals"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/WebDriverIO/#waitforvalue",target:"_blank",rel:"noopener noreferrer"}},[t._v("waitForValue"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/WebDriverIO/#waitnumberofvisibleelements",target:"_blank",rel:"noopener noreferrer"}},[t._v("waitNumberOfVisibleElements"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/WebDriverIO/#switchtonexttab",target:"_blank",rel:"noopener noreferrer"}},[t._v("switchToNextTab"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/WebDriverIO/#switchtoprevioustab",target:"_blank",rel:"noopener noreferrer"}},[t._v("switchToPreviousTab"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/WebDriverIO/#closecurrenttab",target:"_blank",rel:"noopener noreferrer"}},[t._v("closeCurrentTab"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/WebDriverIO/#opennewtab",target:"_blank",rel:"noopener noreferrer"}},[t._v("openNewTab"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/WebDriverIO/#refreshpage",target:"_blank",rel:"noopener noreferrer"}},[t._v("refreshPage"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/WebDriverIO/#scrollpagetobottom",target:"_blank",rel:"noopener noreferrer"}},[t._v("scrollPageToBottom"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/WebDriverIO/#scrollpagetotop",target:"_blank",rel:"noopener noreferrer"}},[t._v("scrollPageToTop"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/helpers/WebDriverIO/#grabbrowserlogs",target:"_blank",rel:"noopener noreferrer"}},[t._v("grabBrowserLogs"),e("OutboundLink")],1)])])]),t._v(" "),e("li",[t._v("Use mkdirp to create output directory. "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/592",target:"_blank",rel:"noopener noreferrer"}},[t._v("#592"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/vkramskikh",target:"_blank",rel:"noopener noreferrer"}},[t._v("vkramskikh"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" Fixed "),e("code",[t._v("seeNumberOfVisibleElements")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/BorisOsipov",target:"_blank",rel:"noopener noreferrer"}},[t._v("BorisOsipov"),e("OutboundLink")],1)]),t._v(" "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/574",target:"_blank",rel:"noopener noreferrer"}},[t._v("#574"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Lots of fixes for promise chain by "),e("strong",[e("a",{attrs:{href:"https://github.com/APshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APshenkin"),e("OutboundLink")],1)]),t._v(" "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/568",target:"_blank",rel:"noopener noreferrer"}},[t._v("#568"),e("OutboundLink")],1),t._v(" "),e("ul",[e("li",[t._v("Fix "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/543",target:"_blank",rel:"noopener noreferrer"}},[t._v("#543"),e("OutboundLink")],1),t._v("- After block not properly executed if Scenario fails")]),t._v(" "),e("li",[t._v("Expected behavior in promise chains: "),e("code",[t._v("_beforeSuite")]),t._v(" hooks from helpers -> "),e("code",[t._v("BeforeSuite")]),t._v(" from test -> "),e("code",[t._v("_before")]),t._v(" hooks from helpers -> "),e("code",[t._v("Before")]),t._v(" from test - > Test steps -> "),e("code",[t._v("_failed")]),t._v(" hooks from helpers (if test failed) -> "),e("code",[t._v("After")]),t._v(" from test -> "),e("code",[t._v("_after")]),t._v(" hooks from helpers -> "),e("code",[t._v("AfterSuite")]),t._v(" from test -> "),e("code",[t._v("_afterSuite")]),t._v(" hook from helpers.")]),t._v(" "),e("li",[t._v("if during test we got errors from any hook (in test or in helper) - stop complete this suite and go to another")]),t._v(" "),e("li",[t._v("if during test we got error from Selenium server - stop complete this suite and go to another")]),t._v(" "),e("li",[t._v("[WebDriverIO][Protractor] if "),e("code",[t._v("restart")]),t._v(" option is false - close all tabs expect one in "),e("code",[t._v("_after")]),t._v(".")]),t._v(" "),e("li",[t._v("Complete "),e("code",[t._v("_after")]),t._v(", "),e("code",[t._v("_afterSuite")]),t._v(" hooks even After/AfterSuite from test was failed")]),t._v(" "),e("li",[t._v("Don't close browser between suites, when "),e("code",[t._v("restart")]),t._v(" option is false. We should start browser only one time and close it only after all tests.")]),t._v(" "),e("li",[t._v("Close tabs and clear local storage, if "),e("code",[t._v("keepCookies")]),t._v(" flag is enabled")])])]),t._v(" "),e("li",[t._v("Fix TypeError when using babel-node or ts-node on node.js 7+ "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/586",target:"_blank",rel:"noopener noreferrer"}},[t._v("#586"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/vkramskikh",target:"_blank",rel:"noopener noreferrer"}},[t._v("vkramskikh"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" fixed usage of "),e("code",[t._v("_locate")])])]),t._v(" "),e("p",[t._v("Special thanks to "),e("strong",[t._v("Andrey Pshenkin")]),t._v(" for his work on this release and the major improvements.")]),t._v(" "),e("h2",{attrs:{id:"_0-6-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-6-3"}},[t._v("#")]),t._v(" 0.6.3")]),t._v(" "),e("ul",[e("li",[t._v('Errors are printed in non-verbose mode. Shows "Selenium not started" and other important errors.')]),t._v(" "),e("li",[t._v("Allowed to set custom test options:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'My scenario'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("build_id")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("123")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("type")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'slow'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("those options can be accessed as "),e("code",[t._v("opts")]),t._v(" property inside a "),e("code",[t._v("test")]),t._v(" object. Can be used in custom listeners.")]),t._v(" "),e("ul",[e("li",[t._v("Added "),e("code",[t._v("docs")]),t._v(" directory to a package.")]),t._v(" "),e("li",[t._v("[WebDriverIO][Protractor][SeleniumWebdriver] Bugfix: cleaning session when "),e("code",[t._v("restart: false")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/tfiwm",target:"_blank",rel:"noopener noreferrer"}},[t._v("tfiwm"),e("OutboundLink")],1)]),t._v(" "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/519",target:"_blank",rel:"noopener noreferrer"}},[t._v("#519"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("[WebDriverIO][Protractor][Nightmare] Added second parameter to "),e("code",[t._v("saveScreenshot")]),t._v(" to allow a full page screenshot. By "),e("strong",[e("a",{attrs:{href:"https://github.com/HughZurname",target:"_blank",rel:"noopener noreferrer"}},[t._v("HughZurname"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added suite object to "),e("code",[t._v("suite.before")]),t._v(" and "),e("code",[t._v("suite.after")]),t._v(" events by "),e("strong",[e("a",{attrs:{href:"https://github.com/implico",target:"_blank",rel:"noopener noreferrer"}},[t._v("implico"),e("OutboundLink")],1)]),t._v(". "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/496",target:"_blank",rel:"noopener noreferrer"}},[t._v("#496"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_0-6-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-6-2"}},[t._v("#")]),t._v(" 0.6.2")]),t._v(" "),e("ul",[e("li",[t._v("Added "),e("code",[t._v("config")]),t._v(" object to "),e("a",{attrs:{href:"http://codecept.io/hooks/#api",target:"_blank",rel:"noopener noreferrer"}},[t._v("public API"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Extended "),e("code",[t._v("index.js")]),t._v(" to include "),e("code",[t._v("actor")]),t._v(" and "),e("code",[t._v("helpers")]),t._v(", so they could be required:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" actor "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'codeceptjs'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("actor"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Added "),e("a",{attrs:{href:"http://codecept.io/hooks/#custom-runner",target:"_blank",rel:"noopener noreferrer"}},[t._v("example for creating custom runner"),e("OutboundLink")],1),t._v(" with public API.")]),t._v(" "),e("li",[t._v("run command to create "),e("code",[t._v("output")]),t._v(" directory if it doesn't exist")]),t._v(" "),e("li",[e("strong",[t._v("[Protractor]")]),t._v(" fixed loading globally installed Protractor")]),t._v(" "),e("li",[t._v("run-multiple command improvements:\n"),e("ul",[e("li",[t._v("create output directories for each process")]),t._v(" "),e("li",[t._v("print process ids in output")])])])]),t._v(" "),e("h2",{attrs:{id:"_0-6-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-6-1"}},[t._v("#")]),t._v(" 0.6.1")]),t._v(" "),e("ul",[e("li",[t._v("Fixed loading hooks")])]),t._v(" "),e("h2",{attrs:{id:"_0-6-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-6-0"}},[t._v("#")]),t._v(" 0.6.0")]),t._v(" "),e("p",[t._v("Major release with extension API and parallel execution.")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("Breaking")]),t._v(" Removed path argument from "),e("code",[t._v("run")]),t._v(". To specify path other than current directory use "),e("code",[t._v("--config")]),t._v(" or "),e("code",[t._v("-c")]),t._v(" option:")])]),t._v(" "),e("p",[t._v("Instead of: "),e("code",[t._v("codeceptjs run tests")]),t._v(" use:")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("# load config and run from tests directory\ncodeceptjs run -c tests/\n\n# or load codecept.json from tests directory\ncodeceptjs run -c tests/codecept.json\n\n# run users_test.js inside tests directory\ncodeceptjs run users_test.js -c tests\n")])])]),e("ul",[e("li",[e("strong",[t._v("Command "),e("code",[t._v("multiple-run")]),t._v(" added")]),t._v(", to execute tests in several browsers in parallel by "),e("strong",[e("a",{attrs:{href:"https://github.com/APshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APshenkin"),e("OutboundLink")],1)]),t._v(" and "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)]),t._v(". "),e("a",{attrs:{href:"http://codecept.io/advanced/#multiple-execution",target:"_blank",rel:"noopener noreferrer"}},[t._v("See documentation"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("Hooks API added to extend CodeceptJS")]),t._v(" with custom listeners and plugins. "),e("a",{attrs:{href:"http://codecept.io/hooks/#hooks_1",target:"_blank",rel:"noopener noreferrer"}},[t._v("See documentation"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[t._v("[Nightmare][WebDriverIO] "),e("code",[t._v("within")]),t._v(" can work with iframes by "),e("strong",[e("a",{attrs:{href:"https://github.com/imvetri",target:"_blank",rel:"noopener noreferrer"}},[t._v("imvetri"),e("OutboundLink")],1)]),t._v(". "),e("a",{attrs:{href:"http://codecept.io/acceptance/#iframes",target:"_blank",rel:"noopener noreferrer"}},[t._v("See documentation"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[t._v("[WebDriverIO][SeleniumWebdriver][Protractor] Default browser changed to "),e("code",[t._v("chrome")])]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Fixed globally locating "),e("code",[t._v("nightmare-upload")]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" added "),e("code",[t._v("seeNumberOfVisibleElements")]),t._v(" method by "),e("strong",[e("a",{attrs:{href:"https://github.com/elarouche",target:"_blank",rel:"noopener noreferrer"}},[t._v("elarouche"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("Exit with non-zero code if init throws an error by "),e("strong",[e("a",{attrs:{href:"https://github.com/rincedd",target:"_blank",rel:"noopener noreferrer"}},[t._v("rincedd"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("New guides published:\n"),e("ul",[e("li",[e("a",{attrs:{href:"http://codecept.io/installation/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Installation"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/hooks/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Hooks"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/advanced/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Advanced Usage"),e("OutboundLink")],1)])])]),t._v(" "),e("li",[t._v("Meta packages published:\n"),e("ul",[e("li",[e("a",{attrs:{href:"https://www.npmjs.com/package/codecept-webdriverio",target:"_blank",rel:"noopener noreferrer"}},[t._v("codecept-webdriverio"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://www.npmjs.com/package/codecept-protractor",target:"_blank",rel:"noopener noreferrer"}},[t._v("codecept-protractor"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("a",{attrs:{href:"https://www.npmjs.com/package/codecept-nightmare",target:"_blank",rel:"noopener noreferrer"}},[t._v("codecept-nightmare"),e("OutboundLink")],1)])])])]),t._v(" "),e("h2",{attrs:{id:"_0-5-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-5-1"}},[t._v("#")]),t._v(" 0.5.1")]),t._v(" "),e("ul",[e("li",[e("a",{attrs:{href:"http://codecept.io/translation/#polish",target:"_blank",rel:"noopener noreferrer"}},[t._v("Polish translation"),e("OutboundLink")],1),t._v(" added by "),e("strong",[e("a",{attrs:{href:"https://github.com/limes",target:"_blank",rel:"noopener noreferrer"}},[t._v("limes"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("Update process exit code so that mocha saves reports before exit by "),e("strong",[e("a",{attrs:{href:"https://github.com/romanovma",target:"_blank",rel:"noopener noreferrer"}},[t._v("romanovma"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" fixed "),e("code",[t._v("getAttributeFrom")]),t._v(" for custom attributes by "),e("strong",[e("a",{attrs:{href:"https://github.com/robrkerr",target:"_blank",rel:"noopener noreferrer"}},[t._v("robrkerr"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Fixed "),e("em",[t._v("UnhandledPromiseRejectionWarning error")]),t._v(" when selecting the dropdown using "),e("code",[t._v("selectOption")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/robrkerr",target:"_blank",rel:"noopener noreferrer"}},[t._v("robrkerr"),e("OutboundLink")],1)]),t._v(". [Se PR.")]),t._v(" "),e("li",[e("strong",[t._v("[Protractor]")]),t._v(" fixed "),e("code",[t._v("pressKey")]),t._v(" method by "),e("strong",[e("a",{attrs:{href:"https://github.com/romanovma",target:"_blank",rel:"noopener noreferrer"}},[t._v("romanovma"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_0-5-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-5-0"}},[t._v("#")]),t._v(" 0.5.0")]),t._v(" "),e("ul",[e("li",[t._v("Protractor ^5.0.0 support (while keeping ^4.0.9 compatibility)")]),t._v(" "),e("li",[t._v("Fix 'fullTitle() is not a function' in exit.js by "),e("strong",[e("a",{attrs:{href:"https://github.com/hubidu",target:"_blank",rel:"noopener noreferrer"}},[t._v("hubidu"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/388",target:"_blank",rel:"noopener noreferrer"}},[t._v("#388"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Fix for "),e("code",[t._v("waitTimeout")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/HughZurname",target:"_blank",rel:"noopener noreferrer"}},[t._v("HughZurname"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/391",target:"_blank",rel:"noopener noreferrer"}},[t._v("#391"),e("OutboundLink")],1),t._v(". Resolves "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/236",target:"_blank",rel:"noopener noreferrer"}},[t._v("#236"),e("OutboundLink")],1),t._v("* Dockerized CodeceptJS setup by "),e("strong",[e("a",{attrs:{href:"https://github.com/artiomnist",target:"_blank",rel:"noopener noreferrer"}},[t._v("artiomnist"),e("OutboundLink")],1)]),t._v(". "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/blob/master/docker/README.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("See reference"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_0-4-16"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-4-16"}},[t._v("#")]),t._v(" 0.4.16")]),t._v(" "),e("ul",[e("li",[t._v("Fixed steps output synchronization (regression since 0.4.14).")]),t._v(" "),e("li",[t._v("[WebDriverIO][Protractor][SeleniumWebdriver][Nightmare] added "),e("code",[t._v("keepCookies")]),t._v(" option to keep cookies between tests with "),e("code",[t._v("restart: false")]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Protractor]")]),t._v(" added "),e("code",[t._v("waitForTimeout")]),t._v(" config option to set default waiting time for all wait* functions.")]),t._v(" "),e("li",[t._v("Fixed "),e("code",[t._v("_test")]),t._v(" hook for helpers by "),e("strong",[e("a",{attrs:{href:"https://github.com/cjhille",target:"_blank",rel:"noopener noreferrer"}},[t._v("cjhille"),e("OutboundLink")],1)]),t._v(".")])]),t._v(" "),e("h2",{attrs:{id:"_0-4-15"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-4-15"}},[t._v("#")]),t._v(" 0.4.15")]),t._v(" "),e("ul",[e("li",[t._v("Fixed regression in recorder sessions: "),e("code",[t._v("oldpromise is not defined")]),t._v(".")])]),t._v(" "),e("h2",{attrs:{id:"_0-4-14"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-4-14"}},[t._v("#")]),t._v(" 0.4.14")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("_beforeStep")]),t._v(" and "),e("code",[t._v("_afterStep")]),t._v(" hooks in helpers are synchronized. Allows to perform additional actions between steps.")])]),t._v(" "),e("p",[t._v("Example: fail if JS error occur in custom helper using WebdriverIO:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token function"}},[t._v("_before")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helpers"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'WebDriverIO'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("browser"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("on")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'error'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("e")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" e"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("_afterStep")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("err"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("throw")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Browser JS error '")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("err"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("Example: fail if JS error occur in custom helper using Nightmare:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token function"}},[t._v("_before")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helpers"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Nightmare'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("browser"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("on")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'page'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("type"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" message"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" stack")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("err "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token template-string"}},[e("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),e("span",{pre:!0,attrs:{class:"token interpolation"}},[e("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("message"),e("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v(" ")]),e("span",{pre:!0,attrs:{class:"token interpolation"}},[e("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("stack"),e("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),e("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("_afterStep")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("err"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("throw")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Error")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Browser JS error '")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("err"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Fixed "),e("code",[t._v("codecept list")]),t._v(" and "),e("code",[t._v("codecept def")]),t._v(" commands.")]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("I.say")]),t._v(" method to print arbitrary comments.")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("say")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I am going to publish post'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("say")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I enter title and body'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("say")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I expect post is visible on site'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" "),e("code",[t._v("restart")]),t._v(" option added. "),e("code",[t._v("restart: false")]),t._v(" allows to run all tests in a single window, disabled by default. By "),e("strong",[e("a",{attrs:{href:"https://github.com/nairvijays99",target:"_blank",rel:"noopener noreferrer"}},[t._v("nairvijays99"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Fixed "),e("code",[t._v("resizeWindow")]),t._v(" command.")]),t._v(" "),e("li",[t._v("[Protractor][SeleniumWebdriver] added "),e("code",[t._v("windowSize")]),t._v(" config option to resize window on start.")]),t._v(" "),e("li",[t._v("Fixed \"Scenario.skip causes 'Cannot read property retries of undefined'\" by "),e("strong",[e("a",{attrs:{href:"https://github.com/MasterOfPoppets",target:"_blank",rel:"noopener noreferrer"}},[t._v("MasterOfPoppets"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed providing absolute paths for tests in config by "),e("strong",[e("a",{attrs:{href:"https://github.com/lennym",target:"_blank",rel:"noopener noreferrer"}},[t._v("lennym"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_0-4-13"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-4-13"}},[t._v("#")]),t._v(" 0.4.13")]),t._v(" "),e("ul",[e("li",[t._v("Added "),e("strong",[t._v("retries")]),t._v(" option "),e("code",[t._v("Feature")]),t._v(" and "),e("code",[t._v("Scenario")]),t._v(" to rerun fragile tests:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Complex JS Stuff'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("retries")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Not that complex'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("retries")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// test goes here")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Added "),e("strong",[t._v("timeout")]),t._v(" option "),e("code",[t._v("Feature")]),t._v(" and "),e("code",[t._v("Scenario")]),t._v(" to specify timeout.")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Complex JS Stuff'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("timeout")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("5000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Not that complex'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("timeout")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// test goes here")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("ul",[e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" Added "),e("code",[t._v("uniqueScreenshotNames")]),t._v(" option to set unique screenshot names for failed tests. By "),e("strong",[e("a",{attrs:{href:"https://github.com/APshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APshenkin"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/299",target:"_blank",rel:"noopener noreferrer"}},[t._v("#299"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" "),e("code",[t._v("clearField")]),t._v(" method improved to accept name/label locators and throw errors.")]),t._v(" "),e("li",[t._v("[Nightmare][SeleniumWebdriver][Protractor] "),e("code",[t._v("clearField")]),t._v(" method added.")]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Fixed "),e("code",[t._v("waitForElement")]),t._v(", and "),e("code",[t._v("waitForVisible")]),t._v(" methods.")]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Fixed "),e("code",[t._v("resizeWindow")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/norisk-it",target:"_blank",rel:"noopener noreferrer"}},[t._v("norisk-it"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added italian "),e("a",{attrs:{href:"http://codecept.io/translation/#italian",target:"_blank",rel:"noopener noreferrer"}},[t._v("translation"),e("OutboundLink")],1),t._v(".")])]),t._v(" "),e("h2",{attrs:{id:"_0-4-12"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-4-12"}},[t._v("#")]),t._v(" 0.4.12")]),t._v(" "),e("ul",[e("li",[t._v("Bootstrap / Teardown improved with "),e("a",{attrs:{href:"http://codecept.io/configuration/#hooks",target:"_blank",rel:"noopener noreferrer"}},[t._v("Hooks"),e("OutboundLink")],1),t._v(". Various options for setup/teardown provided.")]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("--override")]),t._v(" or "),e("code",[t._v("-o")]),t._v(" option for runner to dynamically override configs. Valid JSON should be passed:")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v('codeceptjs run -o \'{ "bootstrap": "bootstrap.js"}\'\ncodeceptjs run -o \'{ "helpers": {"WebDriverIO": {"browser": "chrome"}}}\'\n')])])]),e("ul",[e("li",[t._v("Added "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/tree/master/test/runner",target:"_blank",rel:"noopener noreferrer"}},[t._v("regression tests"),e("OutboundLink")],1),t._v(" for codeceptjs tests runner.")])]),t._v(" "),e("h2",{attrs:{id:"_0-4-11"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-4-11"}},[t._v("#")]),t._v(" 0.4.11")]),t._v(" "),e("ul",[e("li",[t._v("Fixed regression in 0.4.10")]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("bootstrap")]),t._v("/"),e("code",[t._v("teardown")]),t._v(" config options to accept functions as parameters by "),e("strong",[e("a",{attrs:{href:"https://github.com/pscanf",target:"_blank",rel:"noopener noreferrer"}},[t._v("pscanf"),e("OutboundLink")],1)]),t._v(". See updated "),e("a",{attrs:{href:"http://codecept.io/configuration/",target:"_blank",rel:"noopener noreferrer"}},[t._v("config reference"),e("OutboundLink")],1),t._v(" "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/319",target:"_blank",rel:"noopener noreferrer"}},[t._v("#319"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_0-4-10"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-4-10"}},[t._v("#")]),t._v(" 0.4.10")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Protractor]")]),t._v(" Protrctor 4.0.12+ support.")]),t._v(" "),e("li",[t._v("Enabled async bootstrap file by "),e("strong",[e("a",{attrs:{href:"https://github.com/abachar",target:"_blank",rel:"noopener noreferrer"}},[t._v("abachar"),e("OutboundLink")],1)]),t._v(". Use inside "),e("code",[t._v("bootstrap.js")]),t._v(":")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[t._v("module"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("exports")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("done")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// async instructions")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// call done() to continue execution")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// otherwise call done('error description')")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Changed 'pending' to 'skipped' in reports by "),e("strong",[e("a",{attrs:{href:"https://github.com/timja-kainos",target:"_blank",rel:"noopener noreferrer"}},[t._v("timja-kainos"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/315",target:"_blank",rel:"noopener noreferrer"}},[t._v("#315"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_0-4-9"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-4-9"}},[t._v("#")]),t._v(" 0.4.9")]),t._v(" "),e("ul",[e("li",[t._v("[SeleniumWebdriver][Protractor][WebDriverIO][Nightmare] fixed "),e("code",[t._v("executeScript")]),t._v(", "),e("code",[t._v("executeAsyncScript")]),t._v(" to work and return values.")]),t._v(" "),e("li",[t._v("[Protractor][SeleniumWebdriver][WebDriverIO] Added "),e("code",[t._v("waitForInvisible")]),t._v(" and "),e("code",[t._v("waitForStalenessOf")]),t._v(" methods by "),e("strong",[e("a",{attrs:{href:"https://github.com/Nighthawk14",target:"_blank",rel:"noopener noreferrer"}},[t._v("Nighthawk14"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("--config")]),t._v(" option to "),e("code",[t._v("codeceptjs run")]),t._v(" to manually specify config file by "),e("strong",[e("a",{attrs:{href:"https://github.com/cnworks",target:"_blank",rel:"noopener noreferrer"}},[t._v("cnworks"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[Protractor]")]),t._v(" Simplified behavior of "),e("code",[t._v("amOutsideAngularApp")]),t._v(" by using "),e("code",[t._v("ignoreSynchronization")]),t._v(". Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/278",target:"_blank",rel:"noopener noreferrer"}},[t._v("#278"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Set exit code to 1 when test fails at "),e("code",[t._v("Before")]),t._v("/"),e("code",[t._v("After")]),t._v(" hooks. Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/279",target:"_blank",rel:"noopener noreferrer"}},[t._v("#279"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_0-4-8"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-4-8"}},[t._v("#")]),t._v(" 0.4.8")]),t._v(" "),e("ul",[e("li",[t._v("[Protractor][SeleniumWebdriver][Nightmare] added "),e("code",[t._v("moveCursorTo")]),t._v(" method.")]),t._v(" "),e("li",[t._v("[Protractor][SeleniumWebdriver][WebDriverIO] Added "),e("code",[t._v("manualStart")]),t._v(" option to start browser manually in the beginning of test. By "),e("strong",[e("a",{attrs:{href:"https://github.com/cnworks",target:"_blank",rel:"noopener noreferrer"}},[t._v("cnworks"),e("OutboundLink")],1)]),t._v(". [PR"),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/250",target:"_blank",rel:"noopener noreferrer"}},[t._v("#250"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Fixed "),e("code",[t._v("codeceptjs init")]),t._v(" to work with nested directories and file masks.")]),t._v(" "),e("li",[t._v("Fixed "),e("code",[t._v("codeceptjs gt")]),t._v(" to generate test with proper file name suffix. By "),e("strong",[e("a",{attrs:{href:"https://github.com/Zougi",target:"_blank",rel:"noopener noreferrer"}},[t._v("Zougi"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Fixed: Error is thrown when clicking on element which can't be locate. By "),e("strong",[e("a",{attrs:{href:"https://github.com/davetmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davetmik"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" Fixed "),e("code",[t._v("attachFile")]),t._v(" for file upload. By "),e("strong",[e("a",{attrs:{href:"https://github.com/giuband",target:"_blank",rel:"noopener noreferrer"}},[t._v("giuband"),e("OutboundLink")],1)]),t._v(" and "),e("strong",[e("a",{attrs:{href:"https://github.com/davetmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davetmik"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" Add support for timeouts in config and with "),e("code",[t._v("defineTimeouts")]),t._v(" method. By "),e("strong",[e("a",{attrs:{href:"https://github.com/easternbloc",target:"_blank",rel:"noopener noreferrer"}},[t._v("easternbloc"),e("OutboundLink")],1)]),t._v(" "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/258",target:"_blank",rel:"noopener noreferrer"}},[t._v("#258"),e("OutboundLink")],1),t._v(" and "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/267",target:"_blank",rel:"noopener noreferrer"}},[t._v("#267"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/davetmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davetmik"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed hanging of CodeceptJS when error is thrown by event dispatcher. Fix by "),e("strong",[e("a",{attrs:{href:"https://github.com/Zougi",target:"_blank",rel:"noopener noreferrer"}},[t._v("Zougi"),e("OutboundLink")],1)]),t._v(" and "),e("strong",[e("a",{attrs:{href:"https://github.com/davetmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davetmik"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_0-4-7"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-4-7"}},[t._v("#")]),t._v(" 0.4.7")]),t._v(" "),e("ul",[e("li",[t._v("Improved docs for "),e("code",[t._v("BeforeSuite")]),t._v("; fixed its usage with "),e("code",[t._v("restart: false")]),t._v(" option by "),e("strong",[e("a",{attrs:{href:"https://github.com/APshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APshenkin"),e("OutboundLink")],1)]),t._v(".")]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("Nightmare")]),t._v(" to list of available helpers on "),e("code",[t._v("init")]),t._v(".")]),t._v(" "),e("li",[e("strong",[t._v("[Nightmare]")]),t._v(" Removed double "),e("code",[t._v("resizeWindow")]),t._v(" implementation.")])]),t._v(" "),e("h2",{attrs:{id:"_0-4-6"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-4-6"}},[t._v("#")]),t._v(" 0.4.6")]),t._v(" "),e("ul",[e("li",[t._v("Added "),e("code",[t._v("BeforeSuite")]),t._v(" and "),e("code",[t._v("AfterSuite")]),t._v(" hooks to scenario by "),e("strong",[e("a",{attrs:{href:"https://github.com/APshenkin",target:"_blank",rel:"noopener noreferrer"}},[t._v("APshenkin"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"http://codecept.io/basics/#beforesuite",target:"_blank",rel:"noopener noreferrer"}},[t._v("updated documentation"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_0-4-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-4-5"}},[t._v("#")]),t._v(" 0.4.5")]),t._v(" "),e("ul",[e("li",[t._v("Fixed running "),e("code",[t._v("codecept def")]),t._v(" command by "),e("strong",[e("a",{attrs:{href:"https://github.com/jankaspar",target:"_blank",rel:"noopener noreferrer"}},[t._v("jankaspar"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("[Protractor][SeleniumWebdriver] Added support for special keys in "),e("code",[t._v("pressKey")]),t._v(" method. Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/216",target:"_blank",rel:"noopener noreferrer"}},[t._v("#216"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_0-4-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-4-4"}},[t._v("#")]),t._v(" 0.4.4")]),t._v(" "),e("ul",[e("li",[t._v("Interactive shell fixed. Start it by running "),e("code",[t._v("codeceptjs shell")])]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("--profile")]),t._v(" option to "),e("code",[t._v("shell")]),t._v(" command to use dynamic configuration.")]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("--verbose")]),t._v(" option to "),e("code",[t._v("shell")]),t._v(" command for most complete output.")])]),t._v(" "),e("h2",{attrs:{id:"_0-4-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-4-3"}},[t._v("#")]),t._v(" 0.4.3")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Protractor]")]),t._v(" Regression fixed to ^4.0.0 support")]),t._v(" "),e("li",[t._v("Translations included into package.")]),t._v(" "),e("li",[e("code",[t._v("teardown")]),t._v(" option added to config (opposite to "),e("code",[t._v("bootstrap")]),t._v("), expects a JS file to be executed after tests stop.")]),t._v(" "),e("li",[e("a",{attrs:{href:"http://codecept.io/configuration/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Configuration"),e("OutboundLink")],1),t._v(" can be set via JavaScript file "),e("code",[t._v("codecept.conf.js")]),t._v(" instead of "),e("code",[t._v("codecept.json")]),t._v(". It should export "),e("code",[t._v("config")]),t._v(" object:")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside codecept.conf.js")]),t._v("\nexports"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// contents of codecept.js")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("ul",[e("li",[t._v("Added "),e("code",[t._v("--profile")]),t._v(" option to pass its value to "),e("code",[t._v("codecept.conf.js")]),t._v(" as "),e("code",[t._v("process.profile")]),t._v(" for "),e("a",{attrs:{href:"http://codecept.io/configuration#dynamic-configuration",target:"_blank",rel:"noopener noreferrer"}},[t._v("dynamic configuration"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("li",[t._v("Documentation for "),e("a",{attrs:{href:"http://codecept.io/pageobjects#PageFragments",target:"_blank",rel:"noopener noreferrer"}},[t._v("StepObjects, PageFragments"),e("OutboundLink")],1),t._v(" updated.")]),t._v(" "),e("li",[t._v("Documentation for "),e("a",{attrs:{href:"http://codecept.io/configuration/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Configuration"),e("OutboundLink")],1),t._v(" added.")])]),t._v(" "),e("h2",{attrs:{id:"_0-4-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-4-2"}},[t._v("#")]),t._v(" 0.4.2")]),t._v(" "),e("ul",[e("li",[t._v("Added ability to localize tests with translation "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/189",target:"_blank",rel:"noopener noreferrer"}},[t._v("#189"),e("OutboundLink")],1),t._v(". Thanks to "),e("strong",[e("a",{attrs:{href:"https://github.com/abner",target:"_blank",rel:"noopener noreferrer"}},[t._v("abner"),e("OutboundLink")],1)]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Translation]")]),t._v(" ru-RU translation added.")]),t._v(" "),e("li",[e("strong",[t._v("[Translation]")]),t._v(" pt-BR translation added.")])])]),t._v(" "),e("li",[e("strong",[t._v("[Protractor]")]),t._v(" Protractor 4.0.4 compatibility.")]),t._v(" "),e("li",[t._v("[WebDriverIO][SeleniumWebdriver][Protractor] Fixed single browser session mode for "),e("code",[t._v("restart: false")])]),t._v(" "),e("li",[t._v("Fixed using of 3rd party reporters (xunit, mocha-junit-reporter, mochawesome). Added guide.")]),t._v(" "),e("li",[t._v("Documentation for "),e("a",{attrs:{href:"http://codecept.io/translation/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Translation"),e("OutboundLink")],1),t._v(" added.")]),t._v(" "),e("li",[t._v("Documentation for "),e("a",{attrs:{href:"http://codecept.io/reports/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Reports"),e("OutboundLink")],1),t._v(" added.")])]),t._v(" "),e("h2",{attrs:{id:"_0-4-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-4-1"}},[t._v("#")]),t._v(" 0.4.1")]),t._v(" "),e("ul",[e("li",[t._v("Added custom steps to step definition list. See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/174",target:"_blank",rel:"noopener noreferrer"}},[t._v("#174"),e("OutboundLink")],1),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/jayS-de",target:"_blank",rel:"noopener noreferrer"}},[t._v("jayS-de"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" Fixed using "),e("code",[t._v("waitForTimeout")]),t._v(" option by "),e("strong",[e("a",{attrs:{href:"https://github.com/stephane-ruhlmann",target:"_blank",rel:"noopener noreferrer"}},[t._v("stephane-ruhlmann"),e("OutboundLink")],1)]),t._v(". See "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/178",target:"_blank",rel:"noopener noreferrer"}},[t._v("#178"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_0-4-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-4-0"}},[t._v("#")]),t._v(" 0.4.0")]),t._v(" "),e("ul",[e("li",[e("strong",[e("a",{attrs:{href:"http://codecept.io/nightmare",target:"_blank",rel:"noopener noreferrer"}},[t._v("Nightmare"),e("OutboundLink")],1),t._v(" Helper")]),t._v(" added for faster web testing.")]),t._v(" "),e("li",[t._v("[Protractor][SeleniumWebdriver][WebDriverIO] added "),e("code",[t._v("restart: false")]),t._v(" option to reuse one browser between tests (improves speed).")]),t._v(" "),e("li",[e("strong",[t._v("Protractor 4.0")]),t._v(" compatibility. Please upgrade Protractor library.")]),t._v(" "),e("li",[t._v("Added "),e("code",[t._v("--verbose")]),t._v(" option for "),e("code",[t._v("run")]),t._v(" command to log and print global promise and events.")]),t._v(" "),e("li",[t._v("Fixed errors with shutting down and cleanup.")]),t._v(" "),e("li",[t._v("Fixed starting interactive shell with "),e("code",[t._v("codeceptjs shell")]),t._v(".")]),t._v(" "),e("li",[t._v("Fixed handling of failures inside within block")])]),t._v(" "),e("h2",{attrs:{id:"_0-3-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-3-5"}},[t._v("#")]),t._v(" 0.3.5")]),t._v(" "),e("ul",[e("li",[t._v("Introduced IDE autocompletion support for Visual Studio Code and others. Added command for generating TypeScript definitions for "),e("code",[t._v("I")]),t._v(" object. Use it as")])]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",{pre:!0,attrs:{class:"language-text"}},[e("code",[t._v("codeceptjs def\n")])])]),e("p",[t._v("to generate steps definition file and include it into tests by reference. By "),e("strong",[e("a",{attrs:{href:"https://github.com/kaflan",target:"_blank",rel:"noopener noreferrer"}},[t._v("kaflan"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_0-3-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-3-4"}},[t._v("#")]),t._v(" 0.3.4")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Protractor]")]),t._v(" version 3.3.0 comptaibility, NPM 3 compatibility. Please update Protractor!")]),t._v(" "),e("li",[t._v("allows using absolute path for helpers, output, in config and in command line. By "),e("strong",[e("a",{attrs:{href:"https://github.com/denis-sokolov",target:"_blank",rel:"noopener noreferrer"}},[t._v("denis-sokolov"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixes 'Cannot read property '1' of null in generate.js:44' by "),e("strong",[e("a",{attrs:{href:"https://github.com/seethislight",target:"_blank",rel:"noopener noreferrer"}},[t._v("seethislight"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_0-3-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-3-3"}},[t._v("#")]),t._v(" 0.3.3")]),t._v(" "),e("p",[e("strong",[t._v("Fixed global installation")]),t._v(". CodeceptJS can now locate globally located modules.\nCodeceptJS is also recommended for local installation.\nDepending on installation type additional modules (webdriverio, protractor, ...) will be loaded either from local or from global path.")]),t._v(" "),e("h2",{attrs:{id:"_0-3-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-3-2"}},[t._v("#")]),t._v(" 0.3.2")]),t._v(" "),e("ul",[e("li",[t._v("Added "),e("code",[t._v("codeceptjs list")]),t._v(" command which shows all available methods of "),e("code",[t._v("I")]),t._v(" object.")]),t._v(" "),e("li",[t._v("[Protractor][SeleniumWebdriver] fixed closing browser instances")]),t._v(" "),e("li",[t._v("[Protractor][SeleniumWebdriver] "),e("code",[t._v("doubleClick")]),t._v(" method added")]),t._v(" "),e("li",[t._v("[WebDriverIO][Protractor][SeleniumWebdriver] "),e("code",[t._v("doubleClick")]),t._v(" method to locate clickable elements by text, "),e("code",[t._v("context")]),t._v(" option added.")]),t._v(" "),e("li",[t._v("Fixed using assert in generator without yields "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/89",target:"_blank",rel:"noopener noreferrer"}},[t._v("#89"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_0-3-1"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-3-1"}},[t._v("#")]),t._v(" 0.3.1")]),t._v(" "),e("ul",[e("li",[t._v("Fixed "),e("code",[t._v("init")]),t._v(" command")])]),t._v(" "),e("h2",{attrs:{id:"_0-3-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-3-0"}},[t._v("#")]),t._v(" 0.3.0")]),t._v(" "),e("p",[e("strong",[t._v("Breaking Change")]),t._v(": webdriverio package removed from dependencies list. You will need to install it manually after the upgrade.\nStarting from 0.3.0 webdriverio is not the only backend for running selenium tests, so you are free to choose between Protractor, SeleniumWebdriver, and webdriverio and install them.")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[Protractor] helper added")]),t._v(". Now you can test AngularJS applications by using its official library within the unigied CodeceptJS API!")]),t._v(" "),e("li",[e("strong",[t._v("[SeleniumWebdriver] helper added")]),t._v(". You can switch to official JS bindings for Selenium.")]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" "),e("strong",[t._v("updated to webdriverio v 4.0")])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" "),e("code",[t._v("clearField")]),t._v(" method added by "),e("strong",[e("a",{attrs:{href:"https://github.com/fabioel",target:"_blank",rel:"noopener noreferrer"}},[t._v("fabioel"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" added "),e("code",[t._v("dragAndDrop")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/fabioel",target:"_blank",rel:"noopener noreferrer"}},[t._v("fabioel"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" fixed "),e("code",[t._v("scrollTo")]),t._v(" method by "),e("strong",[e("a",{attrs:{href:"https://github.com/sensone",target:"_blank",rel:"noopener noreferrer"}},[t._v("sensone"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" fixed "),e("code",[t._v("windowSize: maximize")]),t._v(" option in config")]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" "),e("code",[t._v("seeElement")]),t._v(" and "),e("code",[t._v("dontSeeElement")]),t._v(" check element for visibility by "),e("strong",[e("a",{attrs:{href:"https://github.com/fabioel",target:"_blank",rel:"noopener noreferrer"}},[t._v("fabioel"),e("OutboundLink")],1)]),t._v(" and "),e("strong",[e("a",{attrs:{href:"https://github.com/davertmik",target:"_blank",rel:"noopener noreferrer"}},[t._v("davertmik"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" "),e("code",[t._v("seeElementInDOM")]),t._v(", "),e("code",[t._v("dontSeeElementInDOM")]),t._v(" added to check element exists on page.")]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" fixed saving screenshots on failure. Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/70",target:"_blank",rel:"noopener noreferrer"}},[t._v("#70"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("fixed "),e("code",[t._v("within")]),t._v(" block doesn't end in output not "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/79",target:"_blank",rel:"noopener noreferrer"}},[t._v("#79"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_0-2-8"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-2-8"}},[t._v("#")]),t._v(" 0.2.8")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" added "),e("code",[t._v("seeNumberOfElements")]),t._v(" by "),e("strong",[e("a",{attrs:{href:"https://github.com/fabioel",target:"_blank",rel:"noopener noreferrer"}},[t._v("fabioel"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"_0-2-7"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-2-7"}},[t._v("#")]),t._v(" 0.2.7")]),t._v(" "),e("ul",[e("li",[t._v("process ends with exit code 1 on error or failure "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/49",target:"_blank",rel:"noopener noreferrer"}},[t._v("#49"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("fixed registereing global Helper "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/57",target:"_blank",rel:"noopener noreferrer"}},[t._v("#57"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("fixed handling error in within block "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/50",target:"_blank",rel:"noopener noreferrer"}},[t._v("#50"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_0-2-6"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-2-6"}},[t._v("#")]),t._v(" 0.2.6")]),t._v(" "),e("ul",[e("li",[t._v("Fixed "),e("code",[t._v("done() was called multiple times")])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" added "),e("code",[t._v("waitToHide")]),t._v(" method by "),e("strong",[e("a",{attrs:{href:"https://github.com/fabioel",target:"_blank",rel:"noopener noreferrer"}},[t._v("fabioel"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Added global "),e("code",[t._v("Helper")]),t._v(" (alias "),e("code",[t._v("codecept_helper)")]),t._v(", object use for writing custom Helpers. Generator updated. Changes to "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/48",target:"_blank",rel:"noopener noreferrer"}},[t._v("#48"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_0-2-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-2-5"}},[t._v("#")]),t._v(" 0.2.5")]),t._v(" "),e("ul",[e("li",[t._v("Fixed issues with using yield inside a test "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/45",target:"_blank",rel:"noopener noreferrer"}},[t._v("#45"),e("OutboundLink")],1),t._v(" "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/47",target:"_blank",rel:"noopener noreferrer"}},[t._v("#47"),e("OutboundLink")],1),t._v(" "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/43",target:"_blank",rel:"noopener noreferrer"}},[t._v("#43"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Fixed generating a custom helper. Helper class is now accessible with "),e("code",[t._v("codecept_helper")]),t._v(" var. Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/48",target:"_blank",rel:"noopener noreferrer"}},[t._v("#48"),e("OutboundLink")],1)])]),t._v(" "),e("h2",{attrs:{id:"_0-2-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-2-4"}},[t._v("#")]),t._v(" 0.2.4")]),t._v(" "),e("ul",[e("li",[t._v("Fixed accessing helpers from custom helper by "),e("strong",[e("a",{attrs:{href:"https://github.com/pim",target:"_blank",rel:"noopener noreferrer"}},[t._v("pim"),e("OutboundLink")],1)]),t._v(".")])]),t._v(" "),e("h2",{attrs:{id:"_0-2-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-2-3"}},[t._v("#")]),t._v(" 0.2.3")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" fixed "),e("code",[t._v("seeInField")]),t._v(" to work with single value elements like: input[type=text], textareas, and multiple: select, input[type=radio], input[type=checkbox]")]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" fixed "),e("code",[t._v("pressKey")]),t._v(", key modifeiers (Control, Command, Alt, Shift) are released after the action")])]),t._v(" "),e("h2",{attrs:{id:"_0-2-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-2-2"}},[t._v("#")]),t._v(" 0.2.2")]),t._v(" "),e("p",[t._v("Fixed generation of custom steps file and page objects.\nPlease replace "),e("code",[t._v("require('codeceptjs/actor')")]),t._v(" to "),e("code",[t._v("actor")]),t._v(" in your "),e("code",[t._v("custom_steps.js")]),t._v(".\nWhenever you need to create "),e("code",[t._v("I")]),t._v(" object (in page objects, custom steps, but not in tests) just call "),e("code",[t._v("actor()")]),t._v(";")]),t._v(" "),e("h2",{attrs:{id:"_0-2-0"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#_0-2-0"}},[t._v("#")]),t._v(" 0.2.0")]),t._v(" "),e("ul",[e("li",[e("strong",[t._v("within")]),t._v(" context hook added")]),t._v(" "),e("li",[e("code",[t._v("--reporter")]),t._v(" option supported")]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" added features and methods:\n"),e("ul",[e("li",[t._v("elements: "),e("code",[t._v("seeElement")]),t._v(", ...")]),t._v(" "),e("li",[t._v("popups: "),e("code",[t._v("acceptPopup")]),t._v(", "),e("code",[t._v("cancelPopup")]),t._v(", "),e("code",[t._v("seeInPopup")]),t._v(",...")]),t._v(" "),e("li",[t._v("navigation: "),e("code",[t._v("moveCursorTo")]),t._v(", "),e("code",[t._v("scrollTo")])]),t._v(" "),e("li",[t._v("saving screenshots on failure; "),e("code",[t._v("saveScreenshot")])]),t._v(" "),e("li",[t._v("cookies: "),e("code",[t._v("setCookie")]),t._v(", "),e("code",[t._v("seeCookie")]),t._v(", ...")]),t._v(" "),e("li",[t._v("source: "),e("code",[t._v("seeInSource")])]),t._v(" "),e("li",[t._v("form: "),e("code",[t._v("seeCheckboxIsChecked")]),t._v(", "),e("code",[t._v("selectOption")]),t._v(" to support multiple selects")]),t._v(" "),e("li",[t._v("keyboard: "),e("code",[t._v("appendField")]),t._v(", "),e("code",[t._v("pressKey")])]),t._v(" "),e("li",[t._v("mouse: "),e("code",[t._v("rightClick")])])])]),t._v(" "),e("li",[t._v("tests added")]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" proxy configuration added by "),e("strong",[e("a",{attrs:{href:"https://github.com/petehouston",target:"_blank",rel:"noopener noreferrer"}},[t._v("petehouston"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("strong",[t._v("[WebDriverIO]")]),t._v(" fixed "),e("code",[t._v("waitForText")]),t._v(" method by "),e("strong",[e("a",{attrs:{href:"https://github.com/roadhump",target:"_blank",rel:"noopener noreferrer"}},[t._v("roadhump"),e("OutboundLink")],1)]),t._v(". Fixes "),e("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/issues/11",target:"_blank",rel:"noopener noreferrer"}},[t._v("#11"),e("OutboundLink")],1)]),t._v(" "),e("li",[t._v("Fixed creating output dir when it already exists on init by "),e("strong",[e("a",{attrs:{href:"https://github.com/alfirin",target:"_blank",rel:"noopener noreferrer"}},[t._v("alfirin"),e("OutboundLink")],1)])]),t._v(" "),e("li",[t._v("Fixed loading of custom helpers")])])])}),[],!1,null,null,null);e.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/41.dd7b7a52.js b/assets/js/41.dd7b7a52.js new file mode 100644 index 00000000..fea6aa5f --- /dev/null +++ b/assets/js/41.dd7b7a52.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[41],{341:function(e,s,t){"use strict";t.r(s);var a=t(14),r=Object(a.a)({},(function(){var e=this,s=e._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[s("h1",{attrs:{id:"commands"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#commands"}},[e._v("#")]),e._v(" Commands")]),e._v(" "),s("h2",{attrs:{id:"run"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#run"}},[e._v("#")]),e._v(" Run")]),e._v(" "),s("p",[e._v("Executes tests. Requires "),s("code",[e._v("codecept.conf.js")]),e._v(" config to be present in provided path.")]),e._v(" "),s("hr"),e._v(" "),s("p",[e._v("Run all tests from current dir")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs run\n")])])]),s("p",[e._v("Load config and run tests from "),s("code",[e._v("test")]),e._v(" dir")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-c")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[e._v("test")]),e._v("\n")])])]),s("p",[e._v('Run only tests with "signin" word in name')]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--grep")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[e._v('"signin"')]),e._v("\n")])])]),s("p",[e._v('Run all tests without "@IEOnly" word in name')]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--grep")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[e._v('"@IEOnly"')]),e._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--invert")]),e._v("\n")])])]),s("p",[e._v("Run single test [path to codecept.js] [test filename]")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs run github_test.js\n")])])]),s("p",[e._v("Run single test with steps printed")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs run github_test.js "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--steps")]),e._v("\n")])])]),s("p",[e._v("Run single test in debug mode (see more in "),s("a",{attrs:{href:"#Debugging"}},[e._v("debugging")]),e._v(" section)")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs run github_test.js "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--debug")]),e._v("\n")])])]),s("p",[e._v("Select config file manually ("),s("code",[e._v("-c")]),e._v(" or "),s("code",[e._v("--config")]),e._v(" option)")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-c")]),e._v(" my.codecept.conf.js\nnpx codeceptjs run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--config")]),e._v(" path/to/codecept.conf.js\n")])])]),s("p",[e._v("Override config on the fly. Provide valid JSON which will be merged into current config:")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--override")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[e._v('\'{ "helpers": {"WebDriver": {"browser": "chrome"}}}\'')]),e._v("\n")])])]),s("p",[e._v("Run tests and produce xunit report:")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--reporter")]),e._v(" xunit\n")])])]),s("p",[e._v("Use any of "),s("a",{attrs:{href:"https://github.com/mochajs/mocha/tree/master/lib/reporters",target:"_blank",rel:"noopener noreferrer"}},[e._v("Mocha reporters"),s("OutboundLink")],1),e._v(" used.")]),e._v(" "),s("h4",{attrs:{id:"debugging"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#debugging"}},[e._v("#")]),e._v(" Debugging")]),e._v(" "),s("p",[e._v("Run single test in debug mode")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--debug")]),e._v("\n")])])]),s("p",[e._v("Run test with internal logs printed.")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--verbose")]),e._v("\n")])])]),s("p",[e._v("Display complete debug output including scheduled promises")]),e._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[e._v("DEBUG=codeceptjs:* npx codeceptjs run\n")])])]),s("h2",{attrs:{id:"run-workers"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#run-workers"}},[e._v("#")]),e._v(" Run Workers")]),e._v(" "),s("p",[e._v("Run tests in parallel threads.")]),e._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[e._v("npx codeceptjs run-workers 3\n")])])]),s("h2",{attrs:{id:"run-rerun"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#run-rerun"}},[e._v("#")]),e._v(" Run Rerun "),s("Badge",{attrs:{text:"Since 3.3.6",type:"warning"}})],1),e._v(" "),s("p",[e._v("Run tests multiple times to detect and fix flaky tests.")]),e._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[e._v("npx codeceptjs run-rerun\n")])])]),s("p",[e._v("For this command configuration is required:")]),e._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// inside codecept.conf.js")]),e._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[e._v("rerun")]),s("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("{")]),e._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// how many times all tests should pass")]),e._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[e._v("minSuccess")]),s("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[e._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// how many times to try to rerun all tests")]),e._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[e._v("maxReruns")]),s("span",{pre:!0,attrs:{class:"token operator"}},[e._v(":")]),e._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[e._v("4")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("}")]),e._v("\n")])])]),s("p",[e._v("Use Cases:")]),e._v(" "),s("ul",[s("li",[s("code",[e._v("minSuccess: 1, maxReruns: 5")]),e._v(" - run all tests no more than 5 times, until first successful run.")]),e._v(" "),s("li",[s("code",[e._v("minSuccess: 3, maxReruns: 5")]),e._v(" - run all tests no more than 5 times, until reaching 3 successfull runs.")]),e._v(" "),s("li",[s("code",[e._v("minSuccess: 10, maxReruns: 10")]),e._v(" - run all tests exactly 10 times, to check their stability.")])]),e._v(" "),s("h2",{attrs:{id:"dry-run"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#dry-run"}},[e._v("#")]),e._v(" Dry Run")]),e._v(" "),s("p",[e._v("Prints test scenarios without executing them")]),e._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[e._v("npx codeceptjs dry-run\n")])])]),s("p",[e._v("When passed "),s("code",[e._v("--steps")]),e._v(" or "),s("code",[e._v("--debug")]),e._v(" option runs tests, disabling all plugins and helpers, so you can get step-by-step report with no tests actually executed.")]),e._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[e._v("npx codeceptjs dry-run --steps\n")])])]),s("p",[e._v("If a plugin needs to be enabled in "),s("code",[e._v("dry-run")]),e._v(" mode, pass its name in "),s("code",[e._v("-p")]),e._v(" option:")]),e._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[e._v("npx codeceptjs dry-run --steps -p allure\n")])])]),s("p",[e._v("If some plugins need to be enabled in "),s("code",[e._v("dry-run")]),e._v(" mode, pass its name in "),s("code",[e._v("-p")]),e._v(" option:")]),e._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[e._v("npx codeceptjs dry-run --steps -p allure,customLocator\n")])])]),s("p",[e._v("If all plugins need to be enabled in "),s("code",[e._v("dry-run")]),e._v(" mode, pass its name in "),s("code",[e._v("-p")]),e._v(" option:")]),e._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[e._v("npx codeceptjs dry-run --steps -p all\n")])])]),s("p",[e._v("To enable bootstrap script in dry-run mode, pass in "),s("code",[e._v("--bootstrap")]),e._v(" option when running with "),s("code",[e._v("--steps")]),e._v(" or "),s("code",[e._v("--debug")])]),e._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[e._v("npx codeceptjs dry-run --steps --bootstrap\n")])])]),s("h2",{attrs:{id:"run-multiple"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#run-multiple"}},[e._v("#")]),e._v(" Run Multiple")]),e._v(" "),s("blockquote",[s("p",[e._v("⚠️ prefer using run-workers instead")])]),e._v(" "),s("p",[e._v("Run multiple suites. Unlike "),s("code",[e._v("run-workers")]),e._v(" spawns processes to execute tests.\n"),s("a",{attrs:{href:"/advanced#multiple-browsers-execution"}},[e._v("Requires additional configuration")]),e._v(" and can be used to execute tests in multiple browsers.")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs run-multiple smoke:chrome regression:firefox\n")])])]),s("h2",{attrs:{id:"init"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#init"}},[e._v("#")]),e._v(" Init")]),e._v(" "),s("p",[e._v("Creates "),s("code",[e._v("codecept.conf.js")]),e._v(" file in current directory:")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs init\n")])])]),s("p",[e._v("Or in provided path")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codecept init "),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[e._v("test")]),e._v("\n")])])]),s("h2",{attrs:{id:"migrate"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#migrate"}},[e._v("#")]),e._v(" Migrate")]),e._v(" "),s("p",[e._v("Migrate your current "),s("code",[e._v("codecept.json")]),e._v(" to "),s("code",[e._v("codecept.conf.js")])]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs migrate\n")])])]),s("h2",{attrs:{id:"shell"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#shell"}},[e._v("#")]),e._v(" Shell")]),e._v(" "),s("p",[e._v("Interactive shell. Allows to try "),s("code",[e._v("I.")]),e._v(" commands in runtime")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs shell\n")])])]),s("h2",{attrs:{id:"generators"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#generators"}},[e._v("#")]),e._v(" Generators")]),e._v(" "),s("p",[e._v("Create new test")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs generate:test\n")])])]),s("p",[e._v("Create new pageobject")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs generate:pageobject\n")])])]),s("p",[e._v("Create new helper")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs generate:helper\n")])])]),s("h2",{attrs:{id:"typescript-definitions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#typescript-definitions"}},[e._v("#")]),e._v(" TypeScript Definitions")]),e._v(" "),s("p",[e._v("TypeScript Definitions allows IDEs to provide autocompletion when writing tests.")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs def\nnpx codeceptjs def "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--config")]),e._v(" path/to/codecept.conf.js\n")])])]),s("p",[e._v("After doing that IDE should provide autocompletion for "),s("code",[e._v("I")]),e._v(" object inside "),s("code",[e._v("Scenario")]),e._v(" and "),s("code",[e._v("within")]),e._v(" blocks.")]),e._v(" "),s("p",[e._v("Add optional parameter "),s("code",[e._v("output")]),e._v(" (or shortcut "),s("code",[e._v("-o")]),e._v("), if you want to place your definition file in specific folder:")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs def "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("--output")]),e._v(" ./tests/typings\nnpx codeceptjs def "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[e._v("-o")]),e._v(" ./tests/typings\n")])])]),s("h2",{attrs:{id:"list-commands"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#list-commands"}},[e._v("#")]),e._v(" List Commands")]),e._v(" "),s("p",[e._v("Prints all available methods of "),s("code",[e._v("I")]),e._v(" to console")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs list\n")])])]),s("h2",{attrs:{id:"local-environment-information"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#local-environment-information"}},[e._v("#")]),e._v(" Local Environment Information")]),e._v(" "),s("p",[e._v("Prints debugging information concerning the local environment")]),e._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[e._v("npx codeceptjs info\n")])])])])}),[],!1,null,null,null);s.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/42.80e62a70.js b/assets/js/42.80e62a70.js new file mode 100644 index 00000000..cb15162a --- /dev/null +++ b/assets/js/42.80e62a70.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[42],{342:function(e,t,r){"use strict";r.r(t);var o=r(14),a=Object(o.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"community-helpers"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#community-helpers"}},[e._v("#")]),e._v(" Community Helpers")]),e._v(" "),t("blockquote",[t("p",[e._v("Share your helpers at our "),t("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/wiki/Community-Helpers",target:"_blank",rel:"noopener noreferrer"}},[e._v("Wiki Page"),t("OutboundLink")],1)])]),e._v(" "),t("p",[e._v("Here is the list of helpers created by our community.\nPlease "),t("strong",[e._v("add your own")]),e._v(" by editing this page.")]),e._v(" "),t("h2",{attrs:{id:"webhooks"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#webhooks"}},[e._v("#")]),e._v(" Webhooks")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/onemolegames/codeceptjs-webhook-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-webhook-helper"),t("OutboundLink")],1),e._v(" - to check webhook calls during the tests.")])]),e._v(" "),t("h2",{attrs:{id:"email-checking"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#email-checking"}},[e._v("#")]),e._v(" Email Checking")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://gist.github.com/schmkr/026732dfa1627b927ff3a08dc31ee884",target:"_blank",rel:"noopener noreferrer"}},[e._v("MailCatcher"),t("OutboundLink")],1),e._v(" - to check emails via Mailcatcher locally.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/tsuemura/codeceptjs-mailhog-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-mailhog-helper"),t("OutboundLink")],1),e._v(" - to check emails via Mailhog locally.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/pavkam/codeceptjs-testmailapp-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-testmailapp-helper"),t("OutboundLink")],1),e._v(" - to check emails via Testmail.app service.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/yurkovychv/codeceptjs-mailosaur",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-mailosaurhelper"),t("OutboundLink")],1),e._v(" - to check emails via "),t("a",{attrs:{href:"https://mailosaur.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Mailosaur"),t("OutboundLink")],1),e._v(" service.")])]),e._v(" "),t("h2",{attrs:{id:"data-sources"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#data-sources"}},[e._v("#")]),e._v(" Data Sources")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/testphony/codeceptjs-httpMock",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-httpmock"),t("OutboundLink")],1),e._v(" - a helper which wraps mockttp library to manage http mock in tests.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/testphony/codeceptjs-http",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-http"),t("OutboundLink")],1),e._v(" - a helper which wraps then-request library to process HTTP requests. It's alternative helper that provides more flexible request management.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/thiagodp/codeceptjs-dbhelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-dbhelper"),t("OutboundLink")],1),e._v(" - allows you to execute queries or commands to databases using database-js.")])]),e._v(" "),t("h2",{attrs:{id:"cloud-providers"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#cloud-providers"}},[e._v("#")]),e._v(" Cloud Providers")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/puneet0191/codeceptjs-saucehelper/",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-saucehelper"),t("OutboundLink")],1),e._v(" - a helper which updates "),t("code",[e._v("Test Names")]),e._v(" & "),t("code",[e._v("Test Results")]),e._v(" on Saucelabs")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/PeterNgTr/codeceptjs-bshelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-bshelper"),t("OutboundLink")],1),e._v(" - a helper which updates "),t("code",[e._v("Test Names")]),e._v(" & "),t("code",[e._v("Test Results")]),e._v(" on Browserstack")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/testingbot/codeceptjs-tbhelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-tbhelper"),t("OutboundLink")],1),e._v(" - a helper which updates "),t("code",[e._v("Test Names")]),e._v(" & "),t("code",[e._v("Test Results")]),e._v(" on TestingBot")])]),e._v(" "),t("h2",{attrs:{id:"visual-testing"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#visual-testing"}},[e._v("#")]),e._v(" Visual-Testing")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/puneet0191/codeceptjs-resemblehelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-resemblehelper"),t("OutboundLink")],1),e._v(" - a helper which helps with visual testing using resemble.js.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.npmjs.com/package/codeceptjs-applitoolshelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-applitoolshelper"),t("OutboundLink")],1),e._v(" - a helper which helps interaction with "),t("a",{attrs:{href:"https://applitools.com",target:"_blank",rel:"noopener noreferrer"}},[e._v("Applitools"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/stracker-phil/codeceptjs-pixelmatchhelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-pixelmatchhelper"),t("OutboundLink")],1),e._v(" - a helper that integrates pixelmatch for visual testing.")])]),e._v(" "),t("h2",{attrs:{id:"reporters"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#reporters"}},[e._v("#")]),e._v(" Reporters")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/reportportal/agent-js-codecept",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-rphelper"),t("OutboundLink")],1),e._v(" is a CodeceptJS helper which can publish tests results on ReportPortal after execution.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.npmjs.com/package/codeceptjs-xray-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-xray-helper"),t("OutboundLink")],1),e._v(" is a CodeceptJS helper which can publish tests results on "),t("a",{attrs:{href:"https://confluence.xpand-it.com/display/XRAYCLOUD/Import+Execution+Results+-+REST",target:"_blank",rel:"noopener noreferrer"}},[e._v("XRAY"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.npmjs.com/package/codeceptjs-xray-cloud-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-xray-cloud-helper"),t("OutboundLink")],1),e._v(" is a helper that automatically retrieves the result of CodeceptJS tests and sends them to XRAY/JIRA(cloud version) via "),t("a",{attrs:{href:"https://docs.getxray.app/display/XRAYCLOUD/Import+Execution+Results+-+REST+v2#ImportExecutionResultsRESTv2-XrayJSONresults",target:"_blank",rel:"noopener noreferrer"}},[e._v("XRAY Cloud API"),t("OutboundLink")],1),e._v(".")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.npmjs.com/package/codeceptjs-slack-reporter",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-slack-reporter"),t("OutboundLink")],1),e._v(" Get a Slack notification when one or more scenarios fail.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/pavkam/codeceptjs-browserlogs-plugin",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-browserlogs-plugin"),t("OutboundLink")],1),e._v(" Record the browser logs for failed tests.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/PeterNgTr/codeceptjs-testrail",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-testrail"),t("OutboundLink")],1),e._v(" - a plugin to integrate with "),t("a",{attrs:{href:"https://www.gurock.com/testrail",target:"_blank",rel:"noopener noreferrer"}},[e._v("Testrail"),t("OutboundLink")],1)]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/cenfun/codeceptjs-monocart-coverage",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-monocart-coverage"),t("OutboundLink")],1),e._v(" - a plugin to generate coverage reports, it integrate with "),t("a",{attrs:{href:"https://github.com/cenfun/monocart-coverage-reports",target:"_blank",rel:"noopener noreferrer"}},[e._v("monocart coverage reports"),t("OutboundLink")],1)])]),e._v(" "),t("h2",{attrs:{id:"browser-request-control"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#browser-request-control"}},[e._v("#")]),e._v(" Browser request control")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/luarmr/codeceptjs-resources-check",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-resources-check"),t("OutboundLink")],1),e._v(" Load a URL with Puppeteer and listen to the requests while the page is loading. Enabling count the number or check the sizes of the requests.")])]),e._v(" "),t("h2",{attrs:{id:"assertion-validations"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#assertion-validations"}},[e._v("#")]),e._v(" Assertion & Validations")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://www.npmjs.com/package/codeceptjs-chai",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-chai"),t("OutboundLink")],1),e._v(" is a CodeceptJS helper which wraps\n"),t("a",{attrs:{href:"https://www.chaijs.com/",target:"_blank",rel:"noopener noreferrer"}},[e._v("chai"),t("OutboundLink")],1),e._v(" library to complete chai assertion steps with CodeceptJS logging.")])]),e._v(" "),t("h2",{attrs:{id:"other"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#other"}},[e._v("#")]),e._v(" Other")]),e._v(" "),t("ul",[t("li",[t("a",{attrs:{href:"https://github.com/thiagodp/codeceptjs-cmdhelper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-cmdhelper"),t("OutboundLink")],1),e._v(" allows you to run commands in the terminal/console")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.npmjs.com/package/eslint-plugin-codeceptjs",target:"_blank",rel:"noopener noreferrer"}},[e._v("eslint-plugin-codeceptjs"),t("OutboundLink")],1),e._v(" Eslint rules for CodeceptJS.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/kobenguyent/codeceptjs-datalayer-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-datalayer-helper"),t("OutboundLink")],1),e._v(" CodeceptJS DataLayer helper helps you to get the datalayer JavaScript array that is used to store information and send this data to the tag manager.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/kobenguyent/codeceptjs-a11y-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-a11y-helper"),t("OutboundLink")],1),e._v(" accessibility tests integrated with CodeceptJS - Playwright-axe")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/kobenguyent/codeceptjs-lighthouse-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-lighthouse-helper"),t("OutboundLink")],1),e._v(" lighthouse audit integrated with CodeceptJS - Playwright")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://www.npmjs.com/package/@viasat/codeceptjs-snowplow-helper",target:"_blank",rel:"noopener noreferrer"}},[e._v("Snowplow Data analytics"),t("OutboundLink")],1),e._v(" - Test your Snowplow events implementations with CodeceptJS and Snowplow Micro.")]),e._v(" "),t("li",[t("a",{attrs:{href:"https://github.com/kobenguyent/codeceptjs-failure-logger",target:"_blank",rel:"noopener noreferrer"}},[e._v("codeceptjs-failure-logger"),t("OutboundLink")],1),e._v(" - Log failed CodeceptJS tests to file")])])])}),[],!1,null,null,null);t.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/43.debb777a.js b/assets/js/43.debb777a.js new file mode 100644 index 00000000..75e0299b --- /dev/null +++ b/assets/js/43.debb777a.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[43],{344:function(t,e,s){"use strict";s.r(e);var a=s(14),n=Object(a.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"configuration"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#configuration"}},[t._v("#")]),t._v(" Configuration")]),t._v(" "),e("p",[t._v("CodeceptJS configuration is set in "),e("code",[t._v("codecept.conf.js")]),t._v(" file.")]),t._v(" "),e("p",[t._v("After running "),e("code",[t._v("codeceptjs init")]),t._v(" it should be saved in test root.")]),t._v(" "),e("table",[e("thead",[e("tr",[e("th",{staticStyle:{"text-align":"left"}},[t._v("Name")]),t._v(" "),e("th",{staticStyle:{"text-align":"left"}},[t._v("Type")]),t._v(" "),e("th",{staticStyle:{"text-align":"left"}},[t._v("Description")])])]),t._v(" "),e("tbody",[e("tr",[e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("bootstrap?")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[t._v("(() => "),e("code",[t._v("Promise")]),t._v("<"),e("code",[t._v("void")]),t._v(">) | "),e("code",[t._v("boolean")]),t._v(" | "),e("code",[t._v("string")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[e("a",{attrs:{href:"https://codecept.io/bootstrap/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Execute code before"),e("OutboundLink")],1),t._v(" tests are run. Can be either JS module file or async function: "),e("code",[t._v("bootstrap: async () => server.launch(),")]),t._v(" or "),e("code",[t._v("bootstrap: 'bootstrap.js',")])])]),t._v(" "),e("tr",[e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("bootstrapAll?")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[t._v("(() => "),e("code",[t._v("Promise")]),t._v("<"),e("code",[t._v("void")]),t._v(">) | "),e("code",[t._v("boolean")]),t._v(" | "),e("code",[t._v("string")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[e("a",{attrs:{href:"https://codecept.io/bootstrap/#bootstrapall-teardownall",target:"_blank",rel:"noopener noreferrer"}},[t._v("Execute code before launching tests in parallel mode"),e("OutboundLink")],1)])]),t._v(" "),e("tr",[e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("gherkin?")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[t._v("{ "),e("code",[t._v("features")]),t._v(": "),e("code",[t._v("string")]),t._v(" | "),e("code",[t._v("string")]),t._v("[] ; "),e("code",[t._v("steps")]),t._v(": "),e("code",[t._v("string")]),t._v("[] }")]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[t._v("Enable "),e("a",{attrs:{href:"https://codecept.io/bdd/#configuration",target:"_blank",rel:"noopener noreferrer"}},[t._v("BDD features"),e("OutboundLink")],1),t._v(". Sample configuration: "),e("code",[t._v('gherkin: { features: "./features/*.feature", steps: ["./step_definitions/steps.js"] }')])])]),t._v(" "),e("tr",[e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("gherkin.features")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("string")]),t._v(" | "),e("code",[t._v("string")]),t._v("[]")]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[t._v("load feature files by pattern. Multiple patterns can be specified as array")])]),t._v(" "),e("tr",[e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("gherkin.steps")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("string")]),t._v("[]")]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[t._v("load step definitions from JS files")])]),t._v(" "),e("tr",[e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("grep?")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("string")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[t._v("Pattern to filter tests by name. This option is useful if you plan to use multiple configs for different environments. To execute only tests with @firefox tag use "),e("code",[t._v("grep: '@firefox'")])])]),t._v(" "),e("tr",[e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("helpers?")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[t._v("{}")]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[t._v("Enable and configure helpers: "),e("code",[t._v("helpers: { Playwright: { url: 'https://mysite.com', browser: 'firefox' } }")])])]),t._v(" "),e("tr",[e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("include?")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("any")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[t._v("Include page objects to access them via dependency injection "),e("code",[t._v('I: "./custom_steps.js", loginPage: "./pages/Login.js", User: "./pages/User.js",')]),t._v(" Configured modules can be injected by name in a Scenario: "),e("code",[t._v("Scenario('test', { I, loginPage, User })")])])]),t._v(" "),e("tr",[e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("mocha?")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("any")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[e("a",{attrs:{href:"https://mochajs.org/#configuring-mocha-nodejs",target:"_blank",rel:"noopener noreferrer"}},[t._v("Mocha test runner options"),e("OutboundLink")],1),t._v(", additional "),e("a",{attrs:{href:"https://codecept.io/reports/#xml",target:"_blank",rel:"noopener noreferrer"}},[t._v("reporters"),e("OutboundLink")],1),t._v(" can be configured here. Example: "),e("code",[t._v('mocha: { "mocha-junit-reporter": { stdout: "./output/console.log", options: { mochaFile: "./output/result.xml", attachments: true //add screenshot for a failed test } } }')])])]),t._v(" "),e("tr",[e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("noGlobals?")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("boolean")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[t._v("Disable registering global functions (Before, Scenario, etc). Not recommended")])]),t._v(" "),e("tr",[e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("output")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("string")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[t._v("Where to store failure screenshots, artifacts, etc "),e("code",[t._v("output: './output'")])])]),t._v(" "),e("tr",[e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("plugins?")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("any")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[t._v("Enable CodeceptJS plugins. Example: "),e("code",[t._v("plugins: { autoDelay: { enabled: true } }")])])]),t._v(" "),e("tr",[e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("require?")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("string")]),t._v("[]")]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[e("a",{attrs:{href:"https://codecept.io/configuration/#require",target:"_blank",rel:"noopener noreferrer"}},[t._v("Require additional JS modules"),e("OutboundLink")],1),t._v(" Example: "),e("code",[t._v('require: ["should"]')])])]),t._v(" "),e("tr",[e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("teardown?")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[t._v("(() => "),e("code",[t._v("Promise")]),t._v("<"),e("code",[t._v("void")]),t._v(">) | "),e("code",[t._v("boolean")]),t._v(" | "),e("code",[t._v("string")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[e("a",{attrs:{href:"https://codecept.io/bootstrap/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Execute code after tests"),e("OutboundLink")],1),t._v(" finished. Can be either JS module file or async function: "),e("code",[t._v("teardown: async () => server.stop(),")]),t._v(" or "),e("code",[t._v("teardown: 'teardown.js',")])])]),t._v(" "),e("tr",[e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("teardownAll?")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[t._v("(() => "),e("code",[t._v("Promise")]),t._v("<"),e("code",[t._v("void")]),t._v(">) | "),e("code",[t._v("boolean")]),t._v(" | "),e("code",[t._v("string")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[e("a",{attrs:{href:"https://codecept.io/bootstrap/#bootstrapall-teardownall",target:"_blank",rel:"noopener noreferrer"}},[t._v("Execute JS code after finishing tests in parallel mode"),e("OutboundLink")],1)])]),t._v(" "),e("tr",[e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("tests")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("string")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[t._v("Pattern to locate CodeceptJS tests. Allows to enter glob pattern or an Array"),e("string",[t._v(" of patterns to match tests / test file names. For tests in JavaScript: "),e("code",[t._v("tests: 'tests/**.test.js'")]),t._v(" For tests in TypeScript: "),e("code",[t._v("tests: 'tests/**.test.ts'")])])],1)]),t._v(" "),e("tr",[e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("timeout?")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("number")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[t._v("Set default tests timeout in seconds. Tests will be killed on no response after timeout. "),e("code",[t._v("timeout: 20,")])])]),t._v(" "),e("tr",[e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("translation?")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[e("code",[t._v("string")])]),t._v(" "),e("td",{staticStyle:{"text-align":"left"}},[t._v("Enable "),e("a",{attrs:{href:"https://codecept.io/translation/",target:"_blank",rel:"noopener noreferrer"}},[t._v("localized test commands"),e("OutboundLink")],1)])])])]),t._v(" "),e("h2",{attrs:{id:"require"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#require"}},[t._v("#")]),t._v(" Require")]),t._v(" "),e("p",[t._v("Requires described module before run. This option is useful for assertion libraries, so you may "),e("code",[t._v("--require should")]),t._v(" instead of manually invoking "),e("code",[t._v("require('should')")]),t._v(" within each test file. It can be used with relative paths, e.g. "),e("code",[t._v('"require": ["/lib/somemodule"]')]),t._v(", and installed packages.")]),t._v(" "),e("p",[t._v("You can register ts-node, so you can use Typescript in tests with ts-node package")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[t._v("exports"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("tests")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./*_test.js'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("timeout")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("output")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("include")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("bootstrap")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("mocha")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// require modules")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("require")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ts-node/register"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"should"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("For array of test pattern")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[t._v("exports"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("tests")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./*_test.js'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./sampleTest.js'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("timeout")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("output")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("include")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("bootstrap")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("mocha")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// require modules")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("require")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ts-node/register"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"should"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("h2",{attrs:{id:"dynamic-configuration"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#dynamic-configuration"}},[t._v("#")]),t._v(" Dynamic Configuration")]),t._v(" "),e("p",[t._v("By default "),e("code",[t._v("codecept.json")]),t._v(" is used for configuration. You can override its values in runtime by using "),e("code",[t._v("--override")]),t._v(" or "),e("code",[t._v("-o")]),t._v(" option in command line, passing valid JSON as a value:")]),t._v(" "),e("div",{staticClass:"language-sh extra-class"},[e("pre",{pre:!0,attrs:{class:"language-sh"}},[e("code",[t._v("codeceptjs run "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-o")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('\'{ "helpers": {"WebDriver": {"browser": "firefox"}}}\'')]),t._v("\n")])])]),e("p",[t._v("You can also switch to JS configuration format for more dynamic options.\nCreate "),e("code",[t._v("codecept.conf.js")]),t._v(" file and make it export "),e("code",[t._v("config")]),t._v(" property.")]),t._v(" "),e("p",[t._v("See the config example:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[t._v("exports"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// load variables from the environment and provide defaults")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" process"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("CODECEPT_URL")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'http://localhost:3000'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" process"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("CLOUDSERVICE_USER")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("key")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" process"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("CLOUDSERVICE_KEY")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("coloredLogs")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("waitForTimeout")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10000")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// don't build monolithic configs")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("mocha")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./mocha.conf.js'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("include")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./src/steps_file.js'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("loginPage")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./src/pages/login_page'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("dashboardPage")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("DashboardPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// here goes config as it was in codecept.conf.ts")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ....")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("(Don't copy-paste this config, it's just demo)")]),t._v(" "),e("p",[t._v("If you prefer to store your configuration files in a different location, or with a different name, you can do that with "),e("code",[t._v("--config")]),t._v(" or `-c:")]),t._v(" "),e("div",{staticClass:"language-sh extra-class"},[e("pre",{pre:!0,attrs:{class:"language-sh"}},[e("code",[t._v("codeceptjs run "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--config")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("./path/to/my/config.js\n")])])]),e("h2",{attrs:{id:"common-configuration-patterns"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#common-configuration-patterns"}},[t._v("#")]),t._v(" Common Configuration Patterns")]),t._v(" "),e("blockquote",[e("p",[t._v("📺 "),e("a",{attrs:{href:"https://www.youtube.com/watch?v=onBnfo_rJa4&t=4s",target:"_blank",rel:"noopener noreferrer"}},[t._v("Watch this material"),e("OutboundLink")],1),t._v(" on YouTube")])]),t._v(" "),e("p",[e("a",{attrs:{href:"https://github.com/codeceptjs/configure",target:"_blank",rel:"noopener noreferrer"}},[e("code",[t._v("@codeceptjs/configure")]),t._v(" package"),e("OutboundLink")],1),t._v(" contains shared recipes for common configuration patterns. This allows to set meta-configuration, independent from a current helper enabled.")]),t._v(" "),e("p",[t._v("Install it and enable to easily switch to headless/window mode, change window size, etc.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" setHeadlessWhen"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" setWindowSize "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@codeceptjs/configure'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("setHeadlessWhen")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("process"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("CI")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("setWindowSize")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1600")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1200")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nexports"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("h2",{attrs:{id:"profile"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#profile"}},[t._v("#")]),t._v(" Profile")]),t._v(" "),e("p",[t._v("Using "),e("code",[t._v("process.env.profile")]),t._v(" you can change the config dynamically.\nIt provides value of "),e("code",[t._v("--profile")]),t._v(" option passed to runner.\nUse its value to change config value on the fly.")]),t._v(" "),e("p",[t._v("For instance, with the config above we can change browser value using "),e("code",[t._v("profile")]),t._v(" option")]),t._v(" "),e("div",{staticClass:"language-sh extra-class"},[e("pre",{pre:!0,attrs:{class:"language-sh"}},[e("code",[t._v("codeceptjs run "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--profile")]),t._v(" firefox\n")])])]),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[t._v("exports"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'http://localhost:3000'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// load value from `profile`")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" process"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("profile "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'firefox'")]),t._v("\n\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/44.a21b159f.js b/assets/js/44.a21b159f.js new file mode 100644 index 00000000..b2ec34b2 --- /dev/null +++ b/assets/js/44.a21b159f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[44],{345:function(t,e,r){"use strict";r.r(e);var o=r(14),n=Object(o.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"continuous-integration"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#continuous-integration"}},[t._v("#")]),t._v(" Continuous Integration")]),t._v(" "),e("blockquote",[e("p",[t._v("Help us improve this article. "),e("a",{attrs:{href:"https://codecept.discourse.group/c/CodeceptJS-issues-in-general/ci/9",target:"_blank",rel:"noopener noreferrer"}},[t._v("Write how did you set up CodeceptJS for CI"),e("OutboundLink")],1),t._v(" and see your post listed here!")])]),t._v(" "),e("p",[t._v("Continuous Integration services allows you to delegate the control of running tests to external system.\nCodeceptJS plays well with all types of CI even when there is no documentation on this topic, it is still easy to set up with any kind of hosted or cloud CI.\nOur community prepared some valuable recipes for setting up CI systems with CodeceptJS.")]),t._v(" "),e("h2",{attrs:{id:"recipes"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#recipes"}},[t._v("#")]),t._v(" Recipes")]),t._v(" "),e("ul",[e("li",[e("h3",{attrs:{id:"codeceptjs-codefresh-integration"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#codeceptjs-codefresh-integration"}},[t._v("#")]),t._v(" "),e("a",{attrs:{href:"https://codecept.discourse.group/t/codeceptjs-codefresh-integration/",target:"_blank",rel:"noopener noreferrer"}},[t._v("CodeceptJS - Codefresh Integration"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("h3",{attrs:{id:"codeceptjs-gitlab-integration"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#codeceptjs-gitlab-integration"}},[t._v("#")]),t._v(" "),e("a",{attrs:{href:"https://codecept.discourse.group/t/codeceptjs-gitlab-integration/",target:"_blank",rel:"noopener noreferrer"}},[t._v("CodeceptJS GitLab Integration"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("h3",{attrs:{id:"codeceptjs-jenkins-integration"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#codeceptjs-jenkins-integration"}},[t._v("#")]),t._v(" "),e("a",{attrs:{href:"https://codecept.discourse.group/t/codeceptjs-jenkins-integration/",target:"_blank",rel:"noopener noreferrer"}},[t._v("CodeceptJS - Jenkins Integration"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("h3",{attrs:{id:"codeceptjs-integration-with-teamcity"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#codeceptjs-integration-with-teamcity"}},[t._v("#")]),t._v(" "),e("a",{attrs:{href:"https://codecept.discourse.group/t/codeceptjs-integration-with-teamcity/",target:"_blank",rel:"noopener noreferrer"}},[t._v("CodeceptJS Integration with TeamCity"),e("OutboundLink")],1)])])])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/45.b3d66826.js b/assets/js/45.b3d66826.js new file mode 100644 index 00000000..ad5249db --- /dev/null +++ b/assets/js/45.b3d66826.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[45],{347:function(t,s,e){"use strict";e.r(s);var a=e(14),n=Object(a.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"extending-codeceptjs-with-custom-helpers"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#extending-codeceptjs-with-custom-helpers"}},[t._v("#")]),t._v(" Extending CodeceptJS With Custom Helpers")]),t._v(" "),s("p",[t._v("Helper is the core concept of CodeceptJS. Helper is a wrapper on top of various libraries providing unified interface around them. When "),s("code",[t._v("I")]),t._v(" object is used in tests it delegates execution of its functions to currently enabled helper classes.")]),t._v(" "),s("p",[t._v("Use Helpers to introduce low-level API to your tests without polluting test scenarios. Helpers can also be used to share functionality across different project and installed as npm packages.")]),t._v(" "),s("h2",{attrs:{id:"development"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#development"}},[t._v("#")]),t._v(" Development")]),t._v(" "),s("p",[t._v("Helpers can be created by running a generator command:")]),t._v(" "),s("div",{staticClass:"language-bash extra-class"},[s("pre",{pre:!0,attrs:{class:"language-bash"}},[s("code",[t._v("npx codeceptjs gh\n")])])]),s("blockquote",[s("p",[t._v("or "),s("code",[t._v("npx codeceptjs generate:helper")])])]),t._v(" "),s("p",[t._v("This command generates a basic helper, append it to "),s("code",[t._v("helpers")]),t._v(" section of config file:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("MyHelper")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./path/to/module'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Helpers are classes inherited from "),s("a",{attrs:{href:"https://github.com/codeceptjs/helper",target:"_blank",rel:"noopener noreferrer"}},[t._v("corresponding abstract class"),s("OutboundLink")],1),t._v(".\nCreated helper file should look like this:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" Helper "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@codeceptjs/helper'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyHelper")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Helper")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// before/after hooks")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("_before")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// remove if not used")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("_after")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// remove if not used")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// add custom methods here")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// If you need to access other helpers")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// use: this.helpers['helperName']")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nmodule"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("exports "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" MyHelper"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("When the helper is enabled in config all methods of a helper class are available in "),s("code",[t._v("I")]),t._v(" object.\nFor instance, if we add a new method to helper class:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" Helper "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@codeceptjs/helper'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyHelper")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Helper")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("doAwesomeThings")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello from MyHelpr'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("We can call a new method from within "),s("code",[t._v("I")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("doAwesomeThings")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("Methods starting with "),s("code",[t._v("_")]),t._v(" are considered special and won't available in "),s("code",[t._v("I")]),t._v(" object.")])]),t._v(" "),s("p",[t._v("Please note, "),s("code",[t._v("I")]),t._v(" object can't be used helper class. As "),s("code",[t._v("I")]),t._v(" object delegates its calls to helper classes, you can't make a circular dependency on it. Instead of calling "),s("code",[t._v("I")]),t._v(" inside a helper, you can get access to other helpers by using "),s("code",[t._v("helpers")]),t._v(" property of a helper. This allows you to access any other enabled helper by its name.")]),t._v(" "),s("p",[t._v("For instance, to perform a click with Playwright helper, do it like this:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("doAwesomeThingsWithPlaywright")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" Playwright "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helpers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n Playwright"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Awesome'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" \n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("After a custom helper is finished you can update CodeceptJS Type Definitions by running:")]),t._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[t._v("npx codeceptjs def "),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(".")]),t._v("\n")])])]),s("p",[t._v("This way, if your tests are written with TypeScript, your IDE will be able to leverage features like autocomplete and so on.")]),t._v(" "),s("h2",{attrs:{id:"accessing-elements"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#accessing-elements"}},[t._v("#")]),t._v(" Accessing Elements")]),t._v(" "),s("p",[t._v("WebDriver, Puppeteer and Playwright drivers provide API for web elements.\nHowever, CodeceptJS do not expose them to tests by design, keeping test to be action focused.\nIf you need to get access to web elements, it is recommended to implement operations for web elements in a custom helper.")]),t._v(" "),s("p",[t._v("To get access for elements, connect to a corresponding helper and use "),s("code",[t._v("_locate")]),t._v(" function to match web elements by CSS or XPath, like you usually do:")]),t._v(" "),s("h3",{attrs:{id:"accessing-elements-in-webdriver"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#accessing-elements-in-webdriver"}},[t._v("#")]),t._v(" Accessing Elements in WebDriver")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside a custom helper")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clickOnEveryElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("locator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" WebDriver "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helpers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" els "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" WebDriver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("_locate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" el "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("of")]),t._v(" els"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" el"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("In this case an an instance of webdriverio element is used.\nTo get a "),s("a",{attrs:{href:"https://webdriver.io/docs/api/",target:"_blank",rel:"noopener noreferrer"}},[t._v("complete API of an element"),s("OutboundLink")],1),t._v(" refer to webdriverio docs.")]),t._v(" "),s("h3",{attrs:{id:"accessing-elements-in-playwright-puppeteer"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#accessing-elements-in-playwright-puppeteer"}},[t._v("#")]),t._v(" Accessing Elements in Playwright & Puppeteer")]),t._v(" "),s("p",[t._v("Similar method can be implemented for Playwright & Puppeteer:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside a custom helper")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clickOnEveryElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("locator")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" Playwright "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helpers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" els "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" Playwright"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("_locate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" el "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("of")]),t._v(" els"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" el"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("In this case "),s("code",[t._v("el")]),t._v(" will be an instance of "),s("a",{attrs:{href:"https://playwright.dev/#version=master&path=docs%2Fapi.md&q=class-elementhandle",target:"_blank",rel:"noopener noreferrer"}},[t._v("ElementHandle"),s("OutboundLink")],1),t._v(" which is similar for Playwright & "),s("a",{attrs:{href:"https://pptr.dev/#?product=Puppeteer&version=master&show=api-class-elementhandle",target:"_blank",rel:"noopener noreferrer"}},[t._v("Puppeteer"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("blockquote",[s("p",[t._v("ℹ There are more "),s("code",[t._v("_locate*")]),t._v(" methods in each helper. Take a look on documentation of a helper you use to see which exact method it exposes.")])]),t._v(" "),s("h2",{attrs:{id:"configuration"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#configuration"}},[t._v("#")]),t._v(" Configuration")]),t._v(" "),s("p",[t._v("Helpers should be enabled inside "),s("code",[t._v("codecept.json")]),t._v(" or "),s("code",[t._v("codecept.conf.js")]),t._v(" files. Command "),s("code",[t._v("generate helper")]),t._v("\ndoes that for you, however you can enable them manually by placing helper to "),s("code",[t._v("helpers")]),t._v(" section inside config file.\nYou can also pass additional config options to your helper from a config - "),s("strong",[t._v("(please note, this example contains comments, while JSON format doesn't support them)")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// here goes standard helpers:")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// WebDriver, Playwright, etc...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// and their configuration")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("MyHelper")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./my_helper.js"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// path to module")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("defaultHost")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://mysite.com"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// custom config param")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Config values will be stored inside helper in "),s("code",[t._v("this.config")]),t._v(". To get "),s("code",[t._v("defaultHost")]),t._v(" value you can use")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("defaultHost\n")])])]),s("p",[t._v("in any place of your helper. You can also redefine config options inside a constructor:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("constructor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("config")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("defaultHost "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n console"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("log")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("defaultHost"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// http://mysite.com/api")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("super")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("config"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"hooks"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#hooks"}},[t._v("#")]),t._v(" Hooks")]),t._v(" "),s("p",[t._v("Helpers may contain several hooks you can use to handle events of a test.\nImplement corresponding methods to them.")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("_init")]),t._v(" - before all tests")]),t._v(" "),s("li",[s("code",[t._v("_finishTest")]),t._v(" - after all tests")]),t._v(" "),s("li",[s("code",[t._v("_before")]),t._v(" - before a test")]),t._v(" "),s("li",[s("code",[t._v("_after")]),t._v(" - after a test")]),t._v(" "),s("li",[s("code",[t._v("_beforeStep")]),t._v(" - before each step")]),t._v(" "),s("li",[s("code",[t._v("_afterStep")]),t._v(" - after each step")]),t._v(" "),s("li",[s("code",[t._v("_beforeSuite")]),t._v(" - before each suite")]),t._v(" "),s("li",[s("code",[t._v("_afterSuite")]),t._v(" - after each suite")]),t._v(" "),s("li",[s("code",[t._v("_passed")]),t._v(" - after a test passed")]),t._v(" "),s("li",[s("code",[t._v("_failed")]),t._v(" - after a test failed")])]),t._v(" "),s("p",[t._v("Each implemented method should return a value as they will be added to global promise chain as well.")]),t._v(" "),s("h2",{attrs:{id:"conditional-retries"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#conditional-retries"}},[t._v("#")]),t._v(" Conditional Retries")]),t._v(" "),s("p",[t._v("It is possible to execute global conditional retries to handle unforseen errors.\nLost connections and network issues are good candidates to be retried whenever they appear.")]),t._v(" "),s("p",[t._v("This can be done inside a helper using the global "),s("RouterLink",{attrs:{to:"/hooks/#api"}},[t._v("promise recorder")]),t._v(":")],1),t._v(" "),s("p",[t._v("Example: Retrying rendering errors in Puppeteer.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("_before")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" recorder "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'codeceptjs'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("recorder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n recorder"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("retry")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("retries")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("when")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("err")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" err"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("message"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("indexOf")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Cannot find context with specified id'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[s("code",[t._v("recorder.retry")]),t._v(" acts similarly to "),s("code",[t._v("I.retry()")]),t._v(" and accepts the same parameters. It expects the "),s("code",[t._v("when")]),t._v(" parameter to be set so it would handle only specific errors and not to retry for every failed step.")]),t._v(" "),s("p",[t._v("Retry rules are available in array "),s("code",[t._v("recorder.retries")]),t._v(". The last retry rule can be disabled by running "),s("code",[t._v("recorder.retries.pop()")]),t._v(";")]),t._v(" "),s("h2",{attrs:{id:"using-typescript"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#using-typescript"}},[t._v("#")]),t._v(" Using Typescript")]),t._v(" "),s("p",[t._v("With Typescript, just simply replacing "),s("code",[t._v("module.exports")]),t._v(" with "),s("code",[t._v("export")]),t._v(" for autocompletion.")]),t._v(" "),s("h2",{attrs:{id:"helper-examples"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#helper-examples"}},[t._v("#")]),t._v(" Helper Examples")]),t._v(" "),s("h3",{attrs:{id:"playwright-example"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#playwright-example"}},[t._v("#")]),t._v(" Playwright Example")]),t._v(" "),s("p",[t._v("In this example we take the power of Playwright to change geolocation in our tests:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" Helper "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@codeceptjs/helper'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyHelper")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Helper")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setGeoLocation")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("longitude"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" latitude")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" browserContext "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helpers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Playwright"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" browserContext"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setGeolocation")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" longitude"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" latitude "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" Playwright"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("refreshPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"webdriver-example"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#webdriver-example"}},[t._v("#")]),t._v(" WebDriver Example")]),t._v(" "),s("p",[t._v("Next example demonstrates how to use WebDriver library to create your own test action. Method "),s("code",[t._v("seeAuthentication")]),t._v(" will use "),s("code",[t._v("browser")]),t._v(" instance of WebDriver to get access to cookies. Standard NodeJS assertion library will be used (you can use any).")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" Helper "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@codeceptjs/helper'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// use any assertion library you like")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" assert "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'assert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyHelper")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Helper")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("/**\n * checks that authentication cookie is set\n */")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeAuthentication")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// access current browser of WebDriver helper")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" WebDriver "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helpers\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" browser "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" WebDriver"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// get all cookies according to https://webdriver.io/api/protocol/cookie.html")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// any helper method should return a value in order to be added to promise chain")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" res "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" browser"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("cookie")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// get values")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" cookies "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("for")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" k "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("in")]),t._v(" cookies"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// check for a cookie")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cookies"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("k"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'logged_in'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("continue")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("equal")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cookies"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("k"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'yes'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n assert"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fail")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cookies"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'logged_in'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Auth cookie not set"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nmodule"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("exports "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" MyHelper"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"puppeteer-example"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#puppeteer-example"}},[t._v("#")]),t._v(" Puppeteer Example")]),t._v(" "),s("p",[t._v("Puppeteer has "),s("a",{attrs:{href:"https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("nice and elegant API"),s("OutboundLink")],1),t._v(" which you can use inside helpers. Accessing "),s("code",[t._v("page")]),t._v(" instance via "),s("code",[t._v("this.helpers.Puppeteer.page")]),t._v(" from inside a helper.")]),t._v(" "),s("p",[t._v("Let's see how we can use "),s("a",{attrs:{href:"https://github.com/GoogleChrome/puppeteer/blob/master/docs/api.md#pageemulateoptions",target:"_blank",rel:"noopener noreferrer"}},[t._v("emulate"),s("OutboundLink")],1),t._v(" function to emulate iPhone browser in a test.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" Helper "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@codeceptjs/helper'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" puppeteer "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'puppeteer'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" iPhone "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" puppeteer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("devices"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'iPhone 6'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("class")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("MyHelper")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("extends")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Helper")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("emulateIPhone")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" page "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helpers"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Puppeteer"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" page"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("emulate")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("iPhone"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n\nmodule"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("exports "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" MyHelper"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/46.4374312d.js b/assets/js/46.4374312d.js new file mode 100644 index 00000000..719db38c --- /dev/null +++ b/assets/js/46.4374312d.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[46],{348:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"data-management"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#data-management"}},[t._v("#")]),t._v(" Data Management")]),t._v(" "),s("blockquote",[s("p",[t._v("This chapter describes data management for external sources. If you are looking for using Data Sets in tests, see "),s("a",{attrs:{href:"https://codecept.io/advanced/#data-drivern-tests",target:"_blank",rel:"noopener noreferrer"}},[t._v("Data Driven Tests"),s("OutboundLink")],1),t._v(" section*")])]),t._v(" "),s("p",[t._v("Managing data for tests is always a tricky issue. How isolate data between tests, how to prepare data for different tests, etc.\nThere are different approaches to solve it:")]),t._v(" "),s("ol",[s("li",[t._v("reset database completely between tests")]),t._v(" "),s("li",[t._v("create unique non-intersecting data sets per each test")]),t._v(" "),s("li",[t._v("create and delete data for a test")])]),t._v(" "),s("p",[t._v("The most efficient way would be to allow test to control its data, i.e. the 3rd option.\nHowever, accessing database directly is not a good idea as database vendor, schema and data are used by application internally and are out of scope of acceptance test.")]),t._v(" "),s("p",[t._v("Today all modern web applications have REST or GraphQL API . So it is a good idea to use it to create data for a test and delete it after.\nAPI is supposed to be a stable interface and it can be used by acceptance tests. CodeceptJS provides 4 helpers for Data Management via REST and GraphQL API.")]),t._v(" "),s("h2",{attrs:{id:"rest"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#rest"}},[t._v("#")]),t._v(" REST")]),t._v(" "),s("p",[s("a",{attrs:{href:"https://codecept.io/helpers/REST/",target:"_blank",rel:"noopener noreferrer"}},[t._v("REST helper"),s("OutboundLink")],1),t._v(" allows sending raw HTTP requests to application.\nThis is a tool to make shortcuts and create your data pragmatically via API. However, it doesn't provide tools for testing APIs, so it should be paired with Playwright or WebDriver helper for browser testing.")]),t._v(" "),s("p",[t._v("Enable REST helper in the config. It is recommended to set "),s("code",[t._v("endpoint")]),t._v(", a base URL for all API requests. If you need some authorization you can optionally set default headers too.")]),t._v(" "),s("p",[t._v("See the sample config:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REST")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("endpoint")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://localhost/api/v1/"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("defaultHeaders")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Auth'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'11111'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Content-Type'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'application/json'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Accept'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'application/json'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'http://localhost'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'chrome'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("REST helper provides basic methods to send requests to application:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendGetRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendPostRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendPutRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendPatchRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendDeleteRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("As well as a method for setting headers: "),s("code",[t._v("haveRequestHeaders")]),t._v(".")]),t._v(" "),s("p",[t._v("Here is a usage example:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" postId "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'check post page'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// valid access token")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("haveRequestHeaders")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("auth")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1111111'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// get the first user")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" user "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendGetRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/users/1'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a post and save its Id")]),t._v("\n postId "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendPostRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/posts'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("author")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" user"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("body")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'some text'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// open browser page of new post")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/posts/2.html'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'some text'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'p.body'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// cleanup created data")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("After")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendDeleteRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/posts/'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("+")]),t._v("postId"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("This can also be used to emulate Ajax requests:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendPostRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/update-status'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("http_x_requested_with")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'xmlhttprequest'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("See complete reference on "),s("a",{attrs:{href:"https://codecept.io/helpers/REST",target:"_blank",rel:"noopener noreferrer"}},[t._v("REST"),s("OutboundLink")],1),t._v(" helper")])]),t._v(" "),s("h2",{attrs:{id:"graphql"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#graphql"}},[t._v("#")]),t._v(" GraphQL")]),t._v(" "),s("p",[s("a",{attrs:{href:"https://codecept.io/helpers/GraphQL/",target:"_blank",rel:"noopener noreferrer"}},[t._v("GraphQL helper"),s("OutboundLink")],1),t._v(" allows sending GraphQL queries and mutations to application, over Http.")]),t._v(" "),s("p",[t._v("This tool allows you to create shortcuts and manage your data pragmatically via a GraphQL endpoint. However, it does not include tools for testing the endpoint, so it should be used in conjunction with WebDriver helpers for browser testing.")]),t._v(" "),s("p",[t._v("Enable GraphQL helper in the config. It is recommended to set "),s("code",[t._v("endpoint")]),t._v(", the URL to which the requests go to. If you need some authorization you can optionally set default headers too.")]),t._v(" "),s("p",[t._v("See the sample config:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("GraphQL")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("endpoint")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://localhost/graphql/"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("defaultHeaders")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Auth'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'11111'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Content-Type'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'application/json'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Accept'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'application/json'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'http://localhost'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'chrome'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("GraphQL helper provides two basic methods to queries and mutations to application:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendQuery")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendMutation")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("As well as a method for setting headers: "),s("code",[t._v("haveRequestHeaders")]),t._v(".")]),t._v(" "),s("p",[t._v("Here is a usage example:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" postData "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'check post page'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// valid access token")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("haveRequestHeaders")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("auth")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1111111'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// get the first user")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" response "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendQuery")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'{ user(id:1) { id }}'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" user "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" response"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a post and save its Id")]),t._v("\n response "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendMutation")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'mutation createPost($input: PostInput!) { createPost(input: $input) { id }}'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("input")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("author")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" user"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("body")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'some text'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n postData "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" response"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'createPost'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// open browser page of new post")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("/posts/")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("postData"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("slug"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v(".html")]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("postData"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("body"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'p.body'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// cleanup created data")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("After")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendMutation")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'mutation deletePost($id: ID!) { deletePost(id: $id) }'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" postData"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("See complete reference on "),s("a",{attrs:{href:"https://codecept.io/helpers/GraphQL",target:"_blank",rel:"noopener noreferrer"}},[t._v("GraphQL"),s("OutboundLink")],1),t._v(" helper")])]),t._v(" "),s("h2",{attrs:{id:"data-generation-with-factories"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#data-generation-with-factories"}},[t._v("#")]),t._v(" Data Generation with Factories")]),t._v(" "),s("p",[t._v("This concept is extended by:")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"https://codecept.io/helpers/ApiDataFactory/",target:"_blank",rel:"noopener noreferrer"}},[t._v("ApiDataFactory"),s("OutboundLink")],1),t._v(" helper, and,")]),t._v(" "),s("li",[s("a",{attrs:{href:"https://codecept.io/helpers/GraphQLDataFactory/",target:"_blank",rel:"noopener noreferrer"}},[t._v("GraphQLDataFactory"),s("OutboundLink")],1),t._v(" helper.")])]),t._v(" "),s("p",[t._v("These helpers build data according to defined rules and use REST API or GraphQL mutations to store them and automatically clean them up after a test.")]),t._v(" "),s("p",[t._v("Just define how many items of any kind you need and the data factory helper will create them for you.")]),t._v(" "),s("p",[t._v("To make this work some preparations are required.")]),t._v(" "),s("p",[t._v("At first, you need data generation libraries which are "),s("a",{attrs:{href:"https://github.com/rosiejs/rosie",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rosie"),s("OutboundLink")],1),t._v(" and "),s("a",{attrs:{href:"https://www.npmjs.com/package/faker",target:"_blank",rel:"noopener noreferrer"}},[t._v("Faker"),s("OutboundLink")],1),t._v(". Faker can generate random names, emails, texts, and Rosie uses them\nto generate objects using factories.")]),t._v(" "),s("p",[t._v("Install rosie and faker to create a first factory:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v("npm i rosie faker "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("--")]),t._v("save"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("-")]),t._v("dev\n")])])]),s("p",[t._v("Then create a module which will export a factory for an entity.\nAnd add that module as a part of the configuration for the helper.")]),t._v(" "),s("p",[t._v("Please look at the respective Factory sections for examples for factory modules and configuration.")]),t._v(" "),s("h3",{attrs:{id:"api-data-factory"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#api-data-factory"}},[t._v("#")]),t._v(" API Data Factory")]),t._v(" "),s("p",[t._v("This helper uses REST API to store the built data and automatically clean them up after a test,\nThe way for setting data for a test is as simple as writing:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside async function")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" post "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("have")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'post'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("haveMultiple")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'comment'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("postId")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" post"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("After completing the preparations under 'Data Generation with Factories', create a factory module which will export a factory.")]),t._v(" "),s("p",[t._v("See the example providing a factory for User generation:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// factories/post.js")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" Factory "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'rosie'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Factory"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" faker "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@faker-js/faker'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nmodule"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("exports "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Factory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("attr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'name'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" faker"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("findName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("attr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'email'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" faker"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("internet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("email")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Next is to configure helper to match factories with API:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ApiDataFactory")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("endpoint")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://user.com/api"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("headers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Content-Type'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'application/json'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Accept'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'application/json'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("factories")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("uri")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/users"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("factory")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./factories/user"')]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Then, calling "),s("code",[t._v("I.have('user')")]),t._v(" inside a test will create a new user for you.\nThis is done by sending POST request to "),s("code",[t._v("/api/users")]),t._v(" URL. Response is returned and can be used in tests.")]),t._v(" "),s("p",[t._v("At the end of a test ApiDataFactory will clean up created record for you. This is done by collecting\nids from crated records and running "),s("code",[t._v("DELETE /api/users/{id}")]),t._v(" requests at the end of a test.\nThis rules can be customized in helper configuration.")]),t._v(" "),s("blockquote",[s("p",[t._v("See complete reference on "),s("a",{attrs:{href:"https://codecept.io/helpers/ApiDataFactory",target:"_blank",rel:"noopener noreferrer"}},[t._v("ApiDataFactory"),s("OutboundLink")],1),t._v(" helper")])]),t._v(" "),s("h3",{attrs:{id:"graphql-data-factory"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#graphql-data-factory"}},[t._v("#")]),t._v(" GraphQL Data Factory")]),t._v(" "),s("p",[t._v("The helper uses GraphQL mutations to store the built data and automatically clean them up after a test.\nThis way for setting data for a test is as simple as writing:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside async function")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" post "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mutateData")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'createPost'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mutateMultiple")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'createComment'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("postId")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" post"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("After completing the preparations under 'Data Generation with Factories', create a factory module which will export a factory.")]),t._v(" "),s("p",[t._v("The object built by the factory is sent as the variables object along with the mutation. So make sure it matches the argument type as detailed in the GraphQL schema. You may want to pass a constructor to the factory to achieve that.")]),t._v(" "),s("p",[t._v("See the example providing a factory for User generation:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// factories/post.js")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" Factory "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'rosie'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Factory"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("var")]),t._v(" faker "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@faker-js/faker'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nmodule"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("exports "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Factory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("buildObj")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("input")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("buildObj "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("attr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'name'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" faker"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("findName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("attr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'email'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" faker"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("internet"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("email")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Next is to configure helper to match factories with API:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("GraphQLDataFactory")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("endpoint")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://user.com/graphql"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("cleanup")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("headers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Content-Type'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'application/json'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Accept'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'application/json'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("factories")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("createUser")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("query")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'mutation createUser($input: UserInput!) { createUser(input: $input) { id name }}'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("factory")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./factories/users'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("revert")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("query")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'mutation deleteUser($id: ID!) { deleteUser(id: $id) }'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("variables")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("id")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Then, calling "),s("code",[t._v("I.mutateData('createUser')")]),t._v(" inside a test will create a new user for you.\nThis is done by sending a GraphQL mutation request over Http to "),s("code",[t._v("/graphql")]),t._v(" endpoint. Response is returned and can be used in tests.")]),t._v(" "),s("p",[t._v("At the end of a test GraphQLDataFactory will clean up created record for you. This is done by collecting\ndata from crated records, creating deletion mutation objects by passing the data to the "),s("code",[t._v("revert")]),t._v(" function provided, and sending deletion mutation objects as requests at the end of a test.\nThis behavior is according the "),s("code",[t._v("revert")]),t._v(" function be customized in helper configuration.\nThe revert function returns an object, that contains the query for deletion, and the variables object to go along with it.")]),t._v(" "),s("blockquote",[s("p",[t._v("See complete reference on "),s("a",{attrs:{href:"https://codecept.io/helpers/GraphQLDataFactory",target:"_blank",rel:"noopener noreferrer"}},[t._v("GraphQLDataFactory"),s("OutboundLink")],1),t._v(" helper")])]),t._v(" "),s("h2",{attrs:{id:"requests-using-browser-session"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#requests-using-browser-session"}},[t._v("#")]),t._v(" Requests Using Browser Session")]),t._v(" "),s("p",[t._v("All the REST, GraphQL, GraphQLDataFactory, and ApiDataFactory helpers allow override requests before sending.\nThis feature can be used to fetch current browser cookies and set them to REST API or GraphQL client.\nBy doing this we can make requests within the current browser session without a need of additional authentication.")]),t._v(" "),s("blockquote",[s("p",[t._v("Sharing browser session with ApiDataFactory or GraphQLDataFactory can be especially useful when you test Single Page Applications")])]),t._v(" "),s("p",[t._v("Since CodeceptJS 2.3.3 there is a simple way to enable shared session for browser and data helpers.\nInstall "),s("a",{attrs:{href:"https://github.com/codeceptjs/configure",target:"_blank",rel:"noopener noreferrer"}},[s("code",[t._v("@codeceptjs/configure")]),s("OutboundLink")],1),t._v(" package:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npm i @codeceptjs/configure --save\n")])])]),s("p",[t._v("Import "),s("code",[t._v("setSharedCookies")]),t._v(" function and call it inside a config:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// in codecept.conf.js")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" setSharedCookies "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@codeceptjs/configure'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// share cookies between browser helpers and REST/GraphQL")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setSharedCookies")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nexports"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Without "),s("code",[t._v("setSharedCookies")]),t._v(" you will need to update the config manually, so a data helper could receive cookies from a browser to make a request. If you would like to configure this process manually, here is an example of doing so:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" cookies"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// share cookies")]),t._v("\n\nexports"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ApiDataFactory")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("endpoint")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'http://local.app/api'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("cleanup")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("headers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Content-Type'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'application/json'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Accept'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'application/json'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("factories")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("uri")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/users"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("factory")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./factories/user"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("onRequest")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("request")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// get a cookie if it's not obtained yet")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("cookies"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" cookies "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" codeceptjs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("container"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'WebDriver'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabCookie")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// add cookies to request for a current request")]),t._v("\n request"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headers "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Cookie")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" cookies"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("map")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("c")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("c"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("join")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'; '")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://local.app/'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'chrome'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("In this case we are accessing WebDriver helper. However, you can replace WebDriver with any helper you use.")]),t._v(" "),s("p",[t._v("The same can be done with GraphQLDataFactory.")]),t._v(" "),s("p",[t._v("The order of helpers is important! ApiDataFactory will clean up created users after a test,\nso it needs browser to be still opened to obtain its cookies.")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/47.5501f340.js b/assets/js/47.5501f340.js new file mode 100644 index 00000000..ac478692 --- /dev/null +++ b/assets/js/47.5501f340.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[47],{346:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("blockquote",[s("p",[t._v("Warning! Detox support in CodeceptJS is experimental. Please try it and help us to test it and improve it. "),s("a",{attrs:{href:"https://github.com/codeceptjs/detox-helper",target:"_blank",rel:"noopener noreferrer"}},[t._v("See Detox helper repository"),s("OutboundLink")],1),t._v(".")])]),t._v(" "),s("p",[t._v("Automated mobile testing can be slow, hard, and ineffective. The price of it goes high, if we take into account fragility of applications, slowness of emulators, and the complexity of debug. "),s("a",{attrs:{href:"/mobile"}},[t._v("Appium")]),t._v(" helps writing mobile tests but not all apps can be tested effectively with it. That's why you should consider using an alternative approach.")]),t._v(" "),s("p",[t._v("Meet "),s("a",{attrs:{href:"https://github.com/wix/Detox",target:"_blank",rel:"noopener noreferrer"}},[t._v("Detox"),s("OutboundLink")],1),t._v(" - grey-box testing solution for mobile testing by Wix.")]),t._v(" "),s("p",[t._v("Unlike, Appium, Detox requires to update mobile application to include test instrumentation, so an application could receive commands from a test, and act accordingly. Let's see pros and cons of such approach:")]),t._v(" "),s("p",[s("strong",[t._v("Pros")]),t._v(":")]),t._v(" "),s("ul",[s("li",[t._v("faster tests")]),t._v(" "),s("li",[t._v("synchronization with application")]),t._v(" "),s("li",[t._v("plays nicely with React Native")])]),t._v(" "),s("p",[s("strong",[t._v("Cons")]),t._v(":")]),t._v(" "),s("ul",[s("li",[t._v("application should be built in a special way")]),t._v(" "),s("li",[t._v("no hybrid applications")]),t._v(" "),s("li",[t._v("native Android apps not supported (except React Native)")]),t._v(" "),s("li",[t._v("no cloud testing with SauceLabs or BrowserStack")])]),t._v(" "),s("p",[t._v("CodeceptJS allows you to try different options and choose the one which works best for you. Both Appium and Detox helpers share the same syntax for testing mobile applications, interactive pause, automatic retries, and other useful features.")]),t._v(" "),s("p",[t._v("CodeceptJS provides next features over standard Detox:")]),t._v(" "),s("ul",[s("li",[s("strong",[t._v("Unified API")]),t._v(". The same test can be executed in Appium or Detox. Unified API helps different teams to use the same syntax and easy port tests from one engine to another.")]),t._v(" "),s("li",[s("a",{attrs:{href:"/basics#pause"}},[t._v("Interactive pause")]),t._v(". When starting/stopping an application takes a long time, debugging and writing tests can be hard. CodeceptJS solves this by pausing an execution and letting you try different commands and locators. With this feature a test can be writtern during one running session.")]),t._v(" "),s("li",[s("a",{attrs:{href:"/basics#retries"}},[t._v("Auto-retries")]),t._v(" using "),s("code",[t._v("retryFailedStepPlugin")]),t._v(" and "),s("code",[t._v("I.retry()")])]),t._v(" "),s("li",[s("strong",[t._v("Cross-Platform testing")]),t._v(" - one test can be executed on different engines. When needed, platform-specific actions and locators can be easily applied.")])]),t._v(" "),s("h2",{attrs:{id:"a-test"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#a-test"}},[t._v("#")]),t._v(" A Test")]),t._v(" "),s("p",[t._v("Compare a test written for Detox using its native syntax:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("element")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("by"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("text")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Welcome'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toBeVisible")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("element")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("by"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'createdAndVisibleText'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toNotExist")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("element")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("by"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'GoButton'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("tap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitFor")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("element")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("by"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'createdAndVisibleText'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toExist")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("withTimeout")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20000")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("expect")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("element")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("by"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'createdAndVisibleText'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("toExist")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("with the same test written using CodeceptJS syntax:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Welcome'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#createdAndVisibleText'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#GoButton'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#createdAndVisibleText'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#createdAndVisibleText'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("As you see, CodeceptJS test is shorter and easier to follow. By simplifying the code and reducing visual noise we make tests easier to follow. But before writing a test we need to prepare an application to be testable with Detox.")]),t._v(" "),s("h2",{attrs:{id:"setup"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#setup"}},[t._v("#")]),t._v(" Setup")]),t._v(" "),s("p",[t._v("It is important to follow "),s("a",{attrs:{href:"https://github.com/wix/Detox/blob/master/docs/Introduction.GettingStarted.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("Detox guide"),s("OutboundLink")],1),t._v(" to build an application with Detox test instrouments included.")]),t._v(" "),s("p",[t._v("After you install Detox, create configuration and build an application using "),s("code",[t._v("detox build")]),t._v(" command, you are ready to integrate Detox with CodeceptJS.")]),t._v(" "),s("p",[t._v("You need to install Detox CodeceptJS helper:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npm i @codeceptjs/detox-helper --save-dev\n")])])]),s("p",[t._v("Then enable this helper in "),s("code",[t._v("codecept.conf.js")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Detox")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@codeceptjs/detox-helper'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("configuration")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("reloadReactNative")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Enable "),s("code",[t._v("reloadReactNative: true")]),t._v(" if you test React Native application.")]),t._v(" "),s("h2",{attrs:{id:"actions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#actions"}},[t._v("#")]),t._v(" Actions")]),t._v(" "),s("p",[t._v("Create test as usual, by running command:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs gt\n")])])]),s("p",[t._v("A test starts when emulator starts and loads an application. So you can begin testing an application.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside a created test")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'test React Native app'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Welcome'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("tap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Start'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Started!'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("The most common actions are:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("tap")]),t._v(" (or "),s("code",[t._v("click")]),t._v(")")]),t._v(" "),s("li",[s("code",[t._v("multiTap")]),t._v(" - perform multiple taps on element")]),t._v(" "),s("li",[s("code",[t._v("longPress")]),t._v(" - longer press")]),t._v(" "),s("li",[s("code",[t._v("fillField")]),t._v(" - fill in value of text field")]),t._v(" "),s("li",[s("code",[t._v("clearField")]),t._v(" - clear value in text field")]),t._v(" "),s("li",[s("code",[t._v("appendField")]),t._v(" - append value in a field")]),t._v(" "),s("li",[s("code",[t._v("swipeUp")]),t._v(", "),s("code",[t._v("swipeDown")]),t._v(", "),s("code",[t._v("swipeLeft")]),t._v(", "),s("code",[t._v("swipeRigth")])])]),t._v(" "),s("p",[t._v("There are also common assertions:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("see")]),t._v(" - to check visibility of text")]),t._v(" "),s("li",[s("code",[t._v("seeElement")]),t._v(" - to check visibility of element")]),t._v(" "),s("li",[s("code",[t._v("seeElementExists")]),t._v(" - to check that element exists")])]),t._v(" "),s("blockquote",[s("p",[t._v("For more details on actions refer to the "),s("a",{attrs:{href:"https://github.com/codeceptjs/detox-helper#api",target:"_blank",rel:"noopener noreferrer"}},[t._v("API reference of Detox helper"),s("OutboundLink")],1),t._v(".")])]),t._v(" "),s("h2",{attrs:{id:"locators"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#locators"}},[t._v("#")]),t._v(" Locators")]),t._v(" "),s("p",[t._v("To write a test you need to learn about available locators in Detox.\nUnlike, Appium there are no XPath locators. Possible locators limited to "),s("code",[t._v("text")]),t._v(", "),s("code",[t._v("id")]),t._v(", "),s("code",[t._v("accessibility id")]),t._v(", and element "),s("code",[t._v("type")]),t._v(". Thus, again, an application should be prepared for testing, to ensure that all active elements are accessible.")]),t._v(" "),s("p",[t._v("Let's see how they can be used:")]),t._v(" "),s("ul",[s("li",[t._v("For "),s("strong",[t._v("ID locators")]),t._v(" use "),s("code",[t._v("#")]),t._v(" prefix (same as in CSS). Example:")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#WelcomeScreen'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("ul",[s("li",[t._v("For "),s("strong",[t._v("accessibility ID")]),t._v(" use "),s("code",[t._v("~")]),t._v(" prefix (as in Appium helper). Example:")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~welcome'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("ul",[s("li",[t._v("Locating elements "),s("strong",[t._v("by text")]),t._v(" requires no prefix, but can be applied only for actions accepting semantic locators.")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("tap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Start'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Username'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("clearField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Username'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Welcome, davert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("ul",[s("li",[t._v("Locating elements "),s("strong",[t._v("by type")]),t._v(" also use no prefix but can be used only where for elements.")])]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Button'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("Text locators can be combined with others, as methods "),s("code",[t._v("tap")]),t._v(", "),s("code",[t._v("click")]),t._v(" and "),s("code",[t._v("see")]),t._v(" can receive a second paramater, which defines a context where to perfrom a search.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// tap "Start" inside "#Layout"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("tap")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Start'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#Layout'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// see text "Welcome" inside "~msg"')]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Welcome'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~msg'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Alternatively, you can use specify locator by using "),s("em",[t._v("strict locator")]),t._v(", passing an object as a locator:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("type")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Button'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("label")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'welcome'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("If you are familiar with Detox API, this is how locators are actually translated: "),s("code",[t._v("{label: 'welcome'}")]),t._v(" => "),s("code",[t._v("by.label('welcome')")]),t._v(".")])]),t._v(" "),s("h3",{attrs:{id:"cross-platform-testing"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#cross-platform-testing"}},[t._v("#")]),t._v(" Cross Platform Testing")]),t._v(" "),s("p",[t._v("If element differs on on iOS and Android you can use "),s("strong",[t._v("cross platform locators")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate element by text on Android")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate element by accessibility id on iOS")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("android")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Start'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ios")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~start'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("When application behavior differs on Android and iOS use platform-specific actions:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("runOnIOS")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// this will be executed only on IOS")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello iOS'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("runOnAndroid")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// this will be executed only on Android")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello Android'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"sample-test"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#sample-test"}},[t._v("#")]),t._v(" Sample Test")]),t._v(" "),s("p",[t._v("Finally, you can get a test looking like this")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Feature")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'My Detox App'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("Scenario")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'save in application'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("setLandscapeOrientation")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#text'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'a new text'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'a new text'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#textValue'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#createdAndVisibleText'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ios")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#GoButton'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("android")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Button'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#createdAndVisibleText'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#createdAndVisibleText'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("runOnAndroid")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Save'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Text Saved'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#message'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("runOnIOS")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'SAVE'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'SAVED!'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("To execute it use "),s("code",[t._v("codeceptjs run")]),t._v(" command")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run\n")])])]),s("p",[t._v("If you want to use detox configuration other than is set in "),s("code",[t._v("codecept.conf.js")]),t._v(" use "),s("code",[t._v("--configuration")]),t._v(" argument:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("npx codeceptjs run --configuration android.test.ci\n")])])]),s("p",[t._v("You can also pass all "),s("a",{attrs:{href:"https://github.com/wix/Detox/blob/master/docs/APIRef.DetoxCLI.md#test",target:"_blank",rel:"noopener noreferrer"}},[t._v("other arguments that Detox CLI supports"),s("OutboundLink")],1),t._v(".")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/48.a504b2b0.js b/assets/js/48.a504b2b0.js new file mode 100644 index 00000000..aabca5f5 --- /dev/null +++ b/assets/js/48.a504b2b0.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[48],{350:function(t,s,e){"use strict";e.r(s);var a=e(14),n=Object(a.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"codeceptjs-docker"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#codeceptjs-docker"}},[t._v("#")]),t._v(" Codeceptjs Docker")]),t._v(" "),s("p",[t._v("CodeceptJS has an "),s("a",{attrs:{href:"https://hub.docker.com/r/codeceptjs/codeceptjs",target:"_blank",rel:"noopener noreferrer"}},[t._v("official docker image"),s("OutboundLink")],1),t._v(" based on Playwright image. Image supports Playwright, Puppeteer, and WebDriver engines.")]),t._v(" "),s("h2",{attrs:{id:"how-to-use"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#how-to-use"}},[t._v("#")]),t._v(" How to Use")]),t._v(" "),s("p",[t._v("This image comes with the necessary dependencies and packages to execute CodeceptJS tests.\nMount in your CodeceptJS config directory into the "),s("code",[t._v("/tests")]),t._v(" directory in the docker container.")]),t._v(" "),s("p",[t._v("Sample mount: "),s("code",[t._v("-v path/to/codecept.conf.js:/tests")])]),t._v(" "),s("p",[t._v("CodeceptJS runner is available inside container as "),s("code",[t._v("codeceptjs")]),t._v(".")]),t._v(" "),s("h3",{attrs:{id:"locally"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#locally"}},[t._v("#")]),t._v(" Locally")]),t._v(" "),s("p",[t._v("You can execute CodeceptJS with Puppeteer locally with no extra configuration.")]),t._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("docker")]),t._v(" run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--net")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("host "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-v")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token environment constant"}},[t._v("$PWD")]),t._v(":/tests codeceptjs/codeceptjs\n")])])]),s("p",[t._v("To customize execution call "),s("code",[t._v("codeceptjs")]),t._v(" command:")]),t._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# run tests with steps")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("docker")]),t._v(" run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--net")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("host "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-v")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token environment constant"}},[t._v("$PWD")]),t._v(":/tests codeceptjs/codeceptjs codeceptjs run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--steps")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# run tests with @user in a name")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("docker")]),t._v(" run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--net")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v("host "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-v")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token environment constant"}},[t._v("$PWD")]),t._v(":/tests codeceptjs/codeceptjs codeceptjs run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--grep")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"@user"')]),t._v("\n")])])]),s("h3",{attrs:{id:"docker-compose"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#docker-compose"}},[t._v("#")]),t._v(" Docker Compose")]),t._v(" "),s("div",{staticClass:"language-yaml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-yaml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'2'")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("services")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("codeceptjs")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("image")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" codeceptjs/codeceptjs\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("depends_on")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v(" firefox\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v(" web\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("volumes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v(" ."),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("/tests\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("web")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("image")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" node\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("command")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" node app/server.js\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("volumes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v(" ."),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("/app\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("firefox")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("image")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" selenium/standalone"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v("firefox"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v("debug"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("2.53.0\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("ports")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'4444'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'5900'")]),t._v("\n")])])]),s("h3",{attrs:{id:"linking-containers"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#linking-containers"}},[t._v("#")]),t._v(" Linking Containers")]),t._v(" "),s("p",[t._v("If using the WebDriver driver, link the container with a Selenium Standalone docker container with an alias of "),s("code",[t._v("selenium")]),t._v(". Additionally, make sure your "),s("code",[t._v("codeceptjs.conf.js")]),t._v(" contains the following to allow CodeceptJS to identify where Selenium is running.")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("host")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" process"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("HOST")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("\n")])])]),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[t._v("$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("docker")]),t._v(" run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-d")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-P")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--name")]),t._v(" selenium-chrome selenium/standalone-chrome\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("# Alternatively, selenium/standalone-firefox can be used")]),t._v("\n\n$ "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("docker")]),t._v(" run "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-it")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--rm")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-v")]),t._v(" /"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("<")]),t._v("path_to_codeceptjs_test_dir"),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">")]),t._v("/:/tests/ "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("--link")]),t._v(" selenium-chrome:selenium codeceptjs/codeceptjs\n")])])]),s("p",[t._v("You may run use "),s("code",[t._v("-v $(pwd)/:tests/")]),t._v(" if running this from the root of your CodeceptJS tests directory.\n"),s("em",[t._v("Note: The output of your test run will appear in your local directory if your output path is "),s("code",[t._v("./output")]),t._v(" in the CodeceptJS config")])]),t._v(" "),s("h3",{attrs:{id:"build"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#build"}},[t._v("#")]),t._v(" Build")]),t._v(" "),s("p",[t._v("To build this image:")]),t._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("docker")]),t._v(" build "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-t")]),t._v(" codeceptjs/codeceptjs "),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(".")]),t._v("\n")])])]),s("ul",[s("li",[t._v("this directory will be added as "),s("code",[t._v("/codecept")]),t._v(" insde container")]),t._v(" "),s("li",[t._v("tests directory is expected to be mounted as "),s("code",[t._v("/tests")])]),t._v(" "),s("li",[s("code",[t._v("codeceptjs")]),t._v(" is a synlink to "),s("code",[t._v("/codecept/bin/codecept.js")])])]),t._v(" "),s("p",[t._v("To build this image with your desired Node version:")]),t._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("docker")]),t._v(" build "),s("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-t")]),t._v(" codeceptjs/codeceptjs "),s("span",{pre:!0,attrs:{class:"token builtin class-name"}},[t._v(".")]),t._v(" --build-arg "),s("span",{pre:!0,attrs:{class:"token assign-left variable"}},[t._v("NODE_VERSION")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("12.10")]),t._v(".0\n")])])]),s("h3",{attrs:{id:"passing-options"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#passing-options"}},[t._v("#")]),t._v(" Passing Options")]),t._v(" "),s("p",[t._v("Options can be passed by calling "),s("code",[t._v("codeceptjs")]),t._v(":")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",{pre:!0,attrs:{class:"language-text"}},[s("code",[t._v("docker run -v $PWD:/tests codeceptjs/codeceptjs codeceptjs run --debug\n")])])]),s("p",[t._v("Alternatively arguments to "),s("code",[t._v("codecept run")]),t._v(" command can be passed via "),s("code",[t._v("CODECEPT_ARGS")]),t._v(" environment variable. For example to run your tests with debug\noutput:")]),t._v(" "),s("div",{staticClass:"language-yaml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-yaml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'2'")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("services")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("codeceptjs")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("image")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" codeceptjs/codeceptjs\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("environment")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v(" CODECEPT_ARGS="),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v("debug\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("volumes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v(" ."),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("/tests\n")])])]),s("p",[t._v("You can also use "),s("code",[t._v("run-workers")]),t._v("to run tests by passing "),s("code",[t._v("NO_OF_WORKERS")]),t._v(", additionally, you can pass more params like showing the debug info as the following example:")]),t._v(" "),s("div",{staticClass:"language-yaml extra-class"},[s("pre",{pre:!0,attrs:{class:"language-yaml"}},[s("code",[s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("version")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'2'")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("services")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("codeceptjs")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("image")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v(" codeceptjs/codeceptjs\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("environment")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v(" NO_OF_WORKERS=3\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v(" CODECEPT_ARGS="),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v("debug\n "),s("span",{pre:!0,attrs:{class:"token key atrule"}},[t._v("volumes")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("-")]),t._v(" ."),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(":")]),t._v("/tests\n")])])])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/49.f3a07a6b.js b/assets/js/49.f3a07a6b.js new file mode 100644 index 00000000..caf34f2a --- /dev/null +++ b/assets/js/49.f3a07a6b.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[49],{349:function(t,a,s){"use strict";s.r(a);var n=s(14),e=Object(n.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"email-testing"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#email-testing"}},[t._v("#")]),t._v(" Email Testing")]),t._v(" "),a("p",[t._v("In End 2 End testing we need to interact with emails.\nEmail delivery can't be tested locally or mocked while testing.\nThat's why for an end to end test you need real emails to be sent and real email address to receive that emails.")]),t._v(" "),a("p",[t._v("Setting up an email server can be hard. So we recommend to use "),a("a",{attrs:{href:"https://mailslurp.com/",target:"_blank",rel:"noopener noreferrer"}},[t._v("MailSlurp"),a("OutboundLink")],1),t._v(" - a service designed for testing emails. It creates disposable mailboxes and provides you an access to those mailboxes via REST API.")]),t._v(" "),a("blockquote",[a("p",[t._v("You no longer need to open your gmail account in a browser to check for an email!")])]),t._v(" "),a("h2",{attrs:{id:"installation"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#installation"}},[t._v("#")]),t._v(" Installation")]),t._v(" "),a("p",[t._v("MailSlurp is a commercial service with a free plan available. To start, "),a("a",{attrs:{href:"https://app.mailslurp.com/",target:"_blank",rel:"noopener noreferrer"}},[t._v("create an account at MailSlurp"),a("OutboundLink")],1),t._v(" and receive API key to use it. Once received install mailslurp helper from npm:")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v("npm i @codeceptjs/mailslurp-helper --save-dev\n")])])]),a("p",[t._v("Then enable a helper in "),a("code",[t._v("codecept.conf.js")]),t._v(":")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("MailSlurp")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("require")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@codeceptjs/mailslurp-helper'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("apiKey")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("After a helper is added, regenerate TypeScript definitions for auto-completion support:")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v("npx codeceptjs def\n")])])]),a("h2",{attrs:{id:"creating-mailbox"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#creating-mailbox"}},[t._v("#")]),t._v(" Creating Mailbox")]),t._v(" "),a("p",[t._v("MailSlurp allows you to create disposable mailboxes. It means that an email address is created for one test only and is deleted afterwards. So you can be confident that no other emails are received at that address.")]),t._v(" "),a("p",[t._v("To create a mailbox use "),a("code",[t._v("I.haveNewMailbox()")]),t._v(" command:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// inside async/await function")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" mailbox "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("haveNewMailbox")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("mailbox object contains:")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("id")]),t._v(" - which is used in next commands")]),t._v(" "),a("li",[a("code",[t._v("emailAddress")]),t._v(" - randomly generated address of a created mailbox.")])]),t._v(" "),a("blockquote",[a("p",[t._v("See "),a("a",{attrs:{href:"https://www.mailslurp.com/guides/getting-started/#create-email-addresses",target:"_blank",rel:"noopener noreferrer"}},[t._v("MailSlurp's guide"),a("OutboundLink")],1),t._v(" for details.")])]),t._v(" "),a("p",[t._v("Mailbox is opened on creation. If you need more than one mailbox and you want to switch between them use "),a("code",[t._v("openMailbox")]),t._v(" method:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" mailbox1 "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("haveNewMailbox")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" mailbox2 "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("haveNewMailbox")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// mailbox2 is now default mailbox")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// switch back to mailbox1")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("openMailbox")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("mailbox1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h2",{attrs:{id:"receiving-an-email"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#receiving-an-email"}},[t._v("#")]),t._v(" Receiving An Email")]),t._v(" "),a("p",[t._v("A last created mailbox will be activated. It means that it will be used by default to check for emails.")]),t._v(" "),a("p",[t._v("After an action that triggers sending an email is performed on a website, you should wait for this email to be received.\nA timeout for waiting an email can be set globally for a helper or for a one call.")]),t._v(" "),a("p",[t._v("Use "),a("code",[t._v("waitForLatestEmail")]),t._v(" function to return the first email from a mailbox:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// to wait for default time (10 secs by default)")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForLatestEmail")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// or specify number of time to wait")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForLatestEmail")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("To specify the exact email to match use "),a("code",[t._v("waitForEmailMatching")]),t._v(" function:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// wait for an email with partial match in subject")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForEmailMatching")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("subject")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Restore password'")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// wait 30 seconds for email with exact subject")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForEmailMatching")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("subject")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'=Forgot password'")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// wait a last email from any address @mysite.com")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForEmailMatching")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("from")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@mysite.com'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// find anything from mysite")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("subject")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Restore password'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// with Restore password in subject")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h2",{attrs:{id:"opening-an-email"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#opening-an-email"}},[t._v("#")]),t._v(" Opening An Email")]),t._v(" "),a("p",[t._v("All wait* functions return a matched email as a result. So you can use it in a test:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" email "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForLatestEmail")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("blockquote",[a("p",[t._v("Please note, that we use "),a("code",[t._v("await")]),t._v(" to assign email. This should be declared inside async function")])]),t._v(" "),a("p",[t._v("An "),a("code",[t._v("email")]),t._v(" object contains the following fields:")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("subject")])]),t._v(" "),a("li",[a("code",[t._v("for")])]),t._v(" "),a("li",[a("code",[t._v("to")])]),t._v(" "),a("li",[a("code",[t._v("body")])])]),t._v(" "),a("p",[t._v('So you can analyze them inside a test. For instance, you can extract an URL from email body and open it.\nThis is how we can emulate "click on this link" behavior in email:')]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// clicking a link in email")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" email "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForLatestEmail")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// extract a link by RegExp")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" url "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" email"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("body"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("match")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token regex"}},[a("span",{pre:!0,attrs:{class:"token regex-delimiter"}},[t._v("/")]),a("span",{pre:!0,attrs:{class:"token regex-source language-regex"}},[t._v("http(s):\\/\\/(.*?)\\s")]),a("span",{pre:!0,attrs:{class:"token regex-delimiter"}},[t._v("/")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// open URL")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("url"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h2",{attrs:{id:"assertions"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#assertions"}},[t._v("#")]),t._v(" Assertions")]),t._v(" "),a("p",[t._v("Assertions are performed on the currently opened email. Email is opened on "),a("code",[t._v("waitFor")]),t._v(" email call, however, you can open an exact email by using "),a("code",[t._v("openEmail")]),t._v(" function.")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" email1 "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForLatestEmail")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// test proceeds...")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" email2 "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForLatestEmail")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("openEmail")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("email1"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// open previous email")]),t._v("\n")])])]),a("p",[t._v("After opening an email assertion methods are available.")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("seeInEmailSubject")])]),t._v(" "),a("li",[a("code",[t._v("seeEmailIsFrom")])]),t._v(" "),a("li",[a("code",[t._v("seeInEmailBody")])]),t._v(" "),a("li",[a("code",[t._v("dontSeeInEmailBody")])]),t._v(" "),a("li",[a("code",[t._v("seeNumberOfEmailAttachments")])]),t._v(" "),a("li",[a("code",[t._v("seeEmailAttachment")])])]),t._v(" "),a("p",[t._v("And here is an example of their usage:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForLatestEmail")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeEmailIsFrom")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@mysite.com'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeInEmailSubject")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Awesome Proposal!'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeInEmailBody")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'To unsubscribe click here'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeNumberOfEmailAttachments")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeEmailAttachment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Attachment_1.pdf'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeEmailAttachment")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Attachment_2.pdf'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("blockquote",[a("p",[t._v("More methods are listed in "),a("a",{attrs:{href:"https://github.com/codeceptjs/mailslurp-helper/blob/master/README.md#api",target:"_blank",rel:"noopener noreferrer"}},[t._v("helper's API reference"),a("OutboundLink")],1)])]),t._v(" "),a("h2",{attrs:{id:"listing-all-emails"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#listing-all-emails"}},[t._v("#")]),t._v(" Listing All Emails")]),t._v(" "),a("p",[t._v("Use "),a("code",[t._v("grabAllEmailsFromMailbox")]),t._v(" to get all emails from a current mailbox:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" emails "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabAllEmailsFromMailbox")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h2",{attrs:{id:"sending-an-email"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#sending-an-email"}},[t._v("#")]),t._v(" Sending an Email")]),t._v(" "),a("p",[t._v("You can also send an email from an active mailbox:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendEmail")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("to")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user@site.com'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("subject")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hello'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("body")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'World'")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])}),[],!1,null,null,null);a.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/5.ff420ac6.js b/assets/js/5.ff420ac6.js new file mode 100644 index 00000000..b41d4d9f --- /dev/null +++ b/assets/js/5.ff420ac6.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[5,26,29],{242:function(t,e,s){},243:function(t,e,s){},244:function(t,e){t.exports=function(t){return null==t}},245:function(t,e,s){},246:function(t,e,s){},247:function(t,e,s){},248:function(t,e,s){},251:function(t,e,s){"use strict";s.r(e);var a=s(267),i=s(261),n=s(239);function r(t,e){return"group"===e.type&&e.children.some(e=>"group"===e.type?r(t,e):"page"===e.type&&Object(n.e)(t,e.path))}var o={name:"SidebarLinks",components:{SidebarGroup:a.default,SidebarLink:i.default},props:["items","depth","sidebarDepth"],data:()=>({openGroupIndex:0}),created(){this.refreshIndex()},watch:{$route(){this.refreshIndex()}},methods:{refreshIndex(){const t=function(t,e){for(let s=0;s-1&&(this.openGroupIndex=t)},toggleGroup(t){this.openGroupIndex=t===this.openGroupIndex?-1:t},isActive(t){return Object(n.e)(this.$route,t.regularPath)}}},l=s(14),c=Object(l.a)(o,(function(){var t=this,e=t._self._c;return t.items.length?e("ul",{staticClass:"sidebar-links"},t._l(t.items,(function(s,a){return e("li",{key:a},["group"===s.type?e("SidebarGroup",{attrs:{item:s,open:a===t.openGroupIndex,collapsable:s.collapsable||s.collapsible,depth:t.depth},on:{toggle:function(e){return t.toggleGroup(a)}}}):e("SidebarLink",{attrs:{sidebarDepth:t.sidebarDepth,item:s}})],1)})),0):t._e()}),[],!1,null,null,null);e.default=c.exports},255:function(t,e,s){},256:function(t,e,s){"use strict";s(242)},257:function(t,e,s){"use strict";s(243)},258:function(t,e,s){},259:function(t,e,s){},260:function(t,e,s){},261:function(t,e,s){"use strict";s.r(e);var a=s(239);function i(t,e,s,a){return t("router-link",{props:{to:e,activeClass:"",exactActiveClass:""},class:{active:a,"sidebar-link":!0}},s)}function n(t,e,s,r,o,l=1){return!e||l>o?null:t("ul",{class:"sidebar-sub-headers"},e.map(e=>{const c=Object(a.e)(r,s+"#"+e.slug);return t("li",{class:"sidebar-sub-header"},[i(t,s+"#"+e.slug,e.title,c),n(t,e.children,s,r,o,l+1)])}))}var r={functional:!0,props:["item","sidebarDepth"],render(t,{parent:{$page:e,$site:s,$route:r,$themeConfig:o,$themeLocaleConfig:l},props:{item:c,sidebarDepth:u}}){const d=Object(a.e)(r,c.path),p="auto"===c.type?d||c.children.some(t=>Object(a.e)(r,c.basePath+"#"+t.slug)):d,h="external"===c.type?function(t,e,s){return t("a",{attrs:{href:e,target:"_blank",rel:"noopener noreferrer"},class:{"sidebar-link":!0}},[s,t("OutboundLink")])}(t,c.path,c.title||c.path):i(t,c.path,c.title||c.path,p),f=[e.frontmatter.sidebarDepth,u,l.sidebarDepth,o.sidebarDepth,1].find(t=>void 0!==t),b=l.displayAllHeaders||o.displayAllHeaders;if("auto"===c.type)return[h,n(t,c.children,c.basePath,r,f)];if((p||b)&&c.headers&&!a.d.test(c.path)){return[h,n(t,Object(a.c)(c.headers),c.path,r,f)]}return h}},o=(s(256),s(257),s(14)),l=Object(o.a)(r,void 0,void 0,!1,null,"a68ca4e6",null);e.default=l.exports},262:function(t,e,s){"use strict";s(245)},263:function(t,e,s){var a=s(11),i=s(4),n=s(10);t.exports=function(t){return"string"==typeof t||!i(t)&&n(t)&&"[object String]"==a(t)}},264:function(t,e,s){"use strict";s(246)},265:function(t,e,s){"use strict";s(247)},266:function(t,e,s){"use strict";s(248)},267:function(t,e,s){"use strict";s.r(e);var a=s(239),i={name:"SidebarGroup",props:["item","open","collapsable","depth"],components:{DropdownTransition:s(249).default},beforeCreate(){this.$options.components.SidebarLinks=s(251).default},methods:{isActive:a.e}},n=(s(266),s(14)),r=Object(n.a)(i,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"sidebar-group",class:[{collapsable:t.collapsable,"is-sub-group":0!==t.depth},"depth-"+t.depth]},[t.item.path?e("router-link",{staticClass:"sidebar-heading clickable",class:{open:t.open,active:t.isActive(t.$route,t.item.path)},attrs:{to:t.item.path},nativeOn:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"open":""}):t._e()]):e("p",{staticClass:"sidebar-heading",class:{open:t.open},on:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"open":""}):t._e()]),t._v(" "),e("DropdownTransition",[t.open||!t.collapsable?e("SidebarLinks",{staticClass:"sidebar-group-items",attrs:{items:t.item.children,sidebarDepth:t.item.sidebarDepth,depth:t.depth+1}}):t._e()],1)],1)}),[],!1,null,null,null);e.default=r.exports},268:function(t,e,s){"use strict";s.r(e);s(265);var a=s(14),i=Object(a.a)({},(function(){var t=this,e=t._self._c;return e("div",{staticClass:"sidebar"},[e("div",{staticClass:"sidebar-wrapper"},[e("h4",[t._v("More Information")]),t._v(" "),e("p",[e("router-link",{attrs:{to:"/videos"}},[t._v("Videos")])],1),t._v(" "),e("p",[e("router-link",{attrs:{to:"/books"}},[t._v("Books & Posts")])],1),t._v(" "),e("p",[e("router-link",{attrs:{to:"/examples"}},[t._v("Examples")])],1),t._v(" "),t._m(0),t._v(" "),e("hr"),t._v(" "),t._m(1),t._v(" "),t._m(2),t._v(" "),t._m(3),t._v(" "),t._m(4)])])}),[function(){var t=this._self._c;return t("p",[t("a",{attrs:{href:"https://codecept.discourse.group/c/cookbook"}},[this._v("Cookbook →")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://sdclabs.com/codeceptjs?utm_source=codecept.io&utm_medium=right&utm_term=link&utm_campaign=reference"}},[this._v("\n Commercial Services →\n ")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://sdclabs.com/trainings/web-automation-codeceptjs?utm_source=codecept.io&utm_medium=rigth&utm_term=link&utm_campaign=reference"}},[this._v("\n Trainings →\n ")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://testomat.io"}},[this._v("\n Testomat.io →\n ")]),t("br"),this._v(" "),t("small",[t("b",[this._v("Plan your end 2 end tests")]),this._v(", collaborate, synchronize with code & get reports!"),t("br"),this._v("\n Join Testomat.io while it is in beta and get a huge discount!")])])},function(){var t=this._self._c;return t("p",{staticClass:"border"},[t("a",{staticClass:"dashed",attrs:{href:"https://opencollective.com/codeceptjs"}},[this._v("\n Support us via OpenCollective!\n ")])])}],!1,null,"0dc4070a",null);e.default=i.exports},273:function(t,e,s){"use strict";s.r(e);var a=s(244),i=s.n(a),n=s(239),r={name:"PageEdit",computed:{lastUpdated(){return this.$page.lastUpdated},lastUpdatedText(){return"string"==typeof this.$themeLocaleConfig.lastUpdated?this.$themeLocaleConfig.lastUpdated:"string"==typeof this.$site.themeConfig.lastUpdated?this.$site.themeConfig.lastUpdated:"Last Updated"},editLink(){const t=i()(this.$page.frontmatter.editLink)?this.$site.themeConfig.editLinks:this.$page.frontmatter.editLink,{repo:e,docsDir:s="",docsBranch:a="master",docsRepo:n=e}=this.$site.themeConfig;return t&&n&&this.$page.relativePath?this.createEditLink(e,n,s,a,this.$page.relativePath):null},editLinkText(){return this.$themeLocaleConfig.editLinkText||this.$site.themeConfig.editLinkText||"Edit this page"}},methods:{createEditLink(t,e,s,a,i){if(/bitbucket.org/.test(t)){return(n.i.test(e)?e:t).replace(n.a,"")+"/src"+`/${a}/`+(s?s.replace(n.a,"")+"/":"")+i+`?mode=edit&spa=0&at=${a}&fileviewer=file-view-default`}return(n.i.test(e)?e:"https://github.com/"+e).replace(n.a,"")+"/edit"+`/${a}/`+(s?s.replace(n.a,"")+"/":"")+i}}},o=(s(262),s(14)),l=Object(o.a)(r,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"page-edit"},[t.editLink?e("div",{staticClass:"edit-link"},[e("a",{attrs:{href:t.editLink,target:"_blank",rel:"noopener noreferrer"}},[t._v(t._s(t.editLinkText))]),t._v(" "),e("OutboundLink")],1):t._e(),t._v(" "),t.lastUpdated?e("div",{staticClass:"last-updated"},[e("span",{staticClass:"prefix"},[t._v(t._s(t.lastUpdatedText)+":")]),t._v(" "),e("span",{staticClass:"time"},[t._v(t._s(t.lastUpdated))])]):t._e()])}),[],!1,null,null,null);e.default=l.exports},274:function(t,e,s){"use strict";s.r(e);s(89);var a=s(239),i=s(263),n=s.n(i),r=s(244),o=s.n(r),l={name:"PageNav",props:["sidebarItems"],computed:{prev(){return u(c.PREV,this)},next(){return u(c.NEXT,this)}}};const c={NEXT:{resolveLink:function(t,e){return d(t,e,1)},getThemeLinkConfig:({nextLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.next},PREV:{resolveLink:function(t,e){return d(t,e,-1)},getThemeLinkConfig:({prevLinks:t})=>t,getPageLinkConfig:({frontmatter:t})=>t.prev}};function u(t,{$themeConfig:e,$page:s,$route:i,$site:r,sidebarItems:l}){const{resolveLink:c,getThemeLinkConfig:u,getPageLinkConfig:d}=t,p=u(e),h=d(s),f=o()(h)?p:h;return!1===f?void 0:n()(f)?Object(a.k)(r.pages,f,i.path):c(s,l)}function d(t,e,s){const a=[];!function t(e,s){for(let a=0,i=e.length;a({isSidebarOpen:!1}),computed:{shouldShowNavbar(){const{themeConfig:t}=this.$site,{frontmatter:e}=this.$page;return!1!==e.navbar&&!1!==t.navbar&&(this.$title||t.logo||t.repo||t.nav||this.$themeLocaleConfig.nav)},shouldShowSidebar(){const{frontmatter:t}=this.$page;return!t.home&&!1!==t.sidebar&&this.sidebarItems.length},sidebarItems(){return Object(c.l)(this.$page,this.$page.regularPath,this.$site,this.$localePath)},pageClasses(){const t=this.$page.frontmatter.pageClass;return[{"no-navbar":!this.shouldShowNavbar,"sidebar-open":this.isSidebarOpen,"no-sidebar":!this.shouldShowSidebar},t]}},mounted(){this.$router.afterEach(()=>{this.isSidebarOpen=!1})},methods:{toggleSidebar(t){this.isSidebarOpen="boolean"==typeof t?t:!this.isSidebarOpen,this.$emit("toggle-sidebar",this.isSidebarOpen)},onTouchStart(t){this.touchStart={x:t.changedTouches[0].clientX,y:t.changedTouches[0].clientY}},onTouchEnd(t){const e=t.changedTouches[0].clientX-this.touchStart.x,s=t.changedTouches[0].clientY-this.touchStart.y;Math.abs(e)>Math.abs(s)&&Math.abs(e)>40&&(e>0&&this.touchStart.x<=80?this.toggleSidebar(!0):this.toggleSidebar(!1))}}},d=s(14),p=Object(d.a)(u,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"theme-container",class:t.pageClasses,on:{touchstart:t.onTouchStart,touchend:t.onTouchEnd}},[t.shouldShowNavbar?e("Navbar",{on:{"toggle-sidebar":t.toggleSidebar}}):t._e(),t._v(" "),e("Subbar"),t._v(" "),e("div",{staticClass:"sidebar-mask",on:{click:function(e){return t.toggleSidebar(!1)}}}),t._v(" "),e("Sidebar",{attrs:{items:t.sidebarItems},on:{"toggle-sidebar":t.toggleSidebar}},[t._t("sidebar-top"),t._v(" "),t._t("sidebar-bottom")],2),t._v(" "),t.$page.frontmatter.home?e("Home"):e("Page",{attrs:{"sidebar-items":t.sidebarItems}},[t._t("page-top"),t._v(" "),t._t("page-bottom")],2),t._v(" "),e("RightSidebar")],1)}),[],!1,null,null,null);e.default=p.exports}}]); \ No newline at end of file diff --git a/assets/js/50.6379a090.js b/assets/js/50.6379a090.js new file mode 100644 index 00000000..5e13da09 --- /dev/null +++ b/assets/js/50.6379a090.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[50],{351:function(e,t,r){"use strict";r.r(t);var a=r(14),s=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h1",{attrs:{id:"examples"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#examples"}},[e._v("#")]),e._v(" Examples")]),e._v(" "),t("blockquote",[t("p",[e._v("Add your own examples to our "),t("a",{attrs:{href:"https://github.com/codeceptjs/CodeceptJS/wiki/Examples",target:"_blank",rel:"noopener noreferrer"}},[e._v("Wiki Page"),t("OutboundLink")],1)])]),e._v(" "),t("h2",{attrs:{id:"todomvc-examples"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#todomvc-examples"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/codecept-js/examples",target:"_blank",rel:"noopener noreferrer"}},[e._v("TodoMVC Examples"),t("OutboundLink")],1)]),e._v(" "),t("p",[t("img",{attrs:{src:"https://github.com/codecept-js/examples/raw/master/todo.png",alt:""}})]),e._v(" "),t("p",[e._v("Playground repository where you can run tests in different helpers on a basic single-page website.")]),e._v(" "),t("p",[e._v("Tests repository demonstrate usage of")]),e._v(" "),t("ul",[t("li",[e._v("Playwright helper")]),e._v(" "),t("li",[e._v("Puppeteer helper")]),e._v(" "),t("li",[e._v("WebDriver helper")]),e._v(" "),t("li",[e._v("TestCafe plugin")]),e._v(" "),t("li",[e._v("Toggle headless mode with env variables")]),e._v(" "),t("li",[e._v("PageObjects")]),e._v(" "),t("li",[e._v("Cucumber syntax")])]),e._v(" "),t("h2",{attrs:{id:"basic-examples"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#basic-examples"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/Codeception/CodeceptJS/tree/master/examples",target:"_blank",rel:"noopener noreferrer"}},[e._v("Basic Examples"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("CodeceptJS repo contains basic tests (both failing and passing) just to show how it works.\nOur team uses it to test new features and run simple scenarios.")]),e._v(" "),t("h2",{attrs:{id:"codeceptjs-cucumber-e2e-framework"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#codeceptjs-cucumber-e2e-framework"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/gkushang/codeceptjs-e2e",target:"_blank",rel:"noopener noreferrer"}},[e._v("CodeceptJS Cucumber E2E Framework"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This repository contains complete E2E framework for CodeceptJS with Cucumber and SauceLabs Integration")]),e._v(" "),t("ul",[t("li",[e._v("CodecepJS-Cucumber E2E Framework")]),e._v(" "),t("li",[e._v("Saucelabs Integration")]),e._v(" "),t("li",[e._v("Run Cross Browser tests in Parallel on SauceLabs with a simple command")]),e._v(" "),t("li",[e._v("Run tests on "),t("code",[e._v("chrome:headless")])]),e._v(" "),t("li",[e._v("Page Objects")]),e._v(" "),t("li",[t("code",[e._v("Should.js")]),e._v(" Assertion Library")]),e._v(" "),t("li",[e._v("Uses "),t("code",[e._v("wdio")]),e._v(" service (selenium-standalone, sauce)")]),e._v(" "),t("li",[e._v("Allure HTML Reports")]),e._v(" "),t("li",[e._v("Uses shared Master configuration")]),e._v(" "),t("li",[e._v("Sample example and feature files of GitHub Features")])]),e._v(" "),t("h2",{attrs:{id:"enterprise-grade-tests"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#enterprise-grade-tests"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/uc-cdis/gen3-qa",target:"_blank",rel:"noopener noreferrer"}},[e._v("Enterprise Grade Tests"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("Complex testing solution by "),t("a",{attrs:{href:"https://github.com/uc-cdis/gen3-qa",target:"_blank",rel:"noopener noreferrer"}},[e._v("Gen3"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("Includes")]),e._v(" "),t("ul",[t("li",[e._v("classical CodeceptJS tests")]),e._v(" "),t("li",[e._v("BDD tests")]),e._v(" "),t("li",[e._v("Jenkins integration")]),e._v(" "),t("li",[e._v("Complex Before/BeforeSuite scripts and more")])]),e._v(" "),t("h2",{attrs:{id:"testing-single-page-application"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#testing-single-page-application"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/bugiratracker/codeceptjs-demo",target:"_blank",rel:"noopener noreferrer"}},[e._v("Testing Single Page Application"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("End 2 end tests for Task management app (currently offline).")]),e._v(" "),t("p",[e._v("Tests repository demonstrate usage of")]),e._v(" "),t("ul",[t("li",[e._v("Puppeteer helper")]),e._v(" "),t("li",[e._v("ApiDataFactory helper")]),e._v(" "),t("li",[e._v("autoLogin plugin")]),e._v(" "),t("li",[e._v("Dynamic config with profiles")])]),e._v(" "),t("h2",{attrs:{id:"practical-e2e-tests"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#practical-e2e-tests"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://gitlab.com/paulvincent/codeceptjs-e2e-testing",target:"_blank",rel:"noopener noreferrer"}},[e._v("Practical E2E Tests"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("Examples from the book "),t("a",{attrs:{href:"https://leanpub.com/codeceptjs/",target:"_blank",rel:"noopener noreferrer"}},[e._v("Practical End 2 End Testing with CodeceptJS"),t("OutboundLink")],1),e._v(" by "),t("strong",[e._v("Paul Vincent Beigang")]),e._v(".")]),e._v(" "),t("p",[e._v("This repository demonstrates usage of:")]),e._v(" "),t("ul",[t("li",[e._v("dynamic config with profiles")]),e._v(" "),t("li",[e._v("testing WYSIWYG editor")]),e._v(" "),t("li",[e._v("GitLab CI")])]),e._v(" "),t("h2",{attrs:{id:"amazon-tests-v2"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#amazon-tests-v2"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://gitlab.com/thanhnguyendh/codeceptjs-wdio-services",target:"_blank",rel:"noopener noreferrer"}},[e._v("Amazon Tests v2"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("Testing Amazon website using Selenium WebDriver.")]),e._v(" "),t("p",[e._v("This repository demonstrates usage of:")]),e._v(" "),t("ul",[t("li",[e._v("WebDriver helper")]),e._v(" "),t("li",[e._v("Page Objects")]),e._v(" "),t("li",[e._v("wdio services (selenium-standalone)")]),e._v(" "),t("li",[e._v("Parallel execution")]),e._v(" "),t("li",[e._v("GitLab CI setup")])]),e._v(" "),t("h2",{attrs:{id:"tests-with-docker-compose"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#tests-with-docker-compose"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/mathesouza/codeceptjs-docker-compose",target:"_blank",rel:"noopener noreferrer"}},[e._v("Tests with Docker Compose"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("Running CodeceptJS tests with Docker Compose")]),e._v(" "),t("p",[e._v("This repository demonstrates usage of:")]),e._v(" "),t("ul",[t("li",[e._v("CodeceptJS Docker image")]),e._v(" "),t("li",[e._v("WebDriver helper")]),e._v(" "),t("li",[e._v("Allure plugin")])]),e._v(" "),t("h2",{attrs:{id:"angularjs-example-tests"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#angularjs-example-tests"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/armno/angular-e2e-codeceptjs-example",target:"_blank",rel:"noopener noreferrer"}},[e._v("AngularJS Example Tests"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("Based on "),t("a",{attrs:{href:"https://medium.com/@armno/setting-up-end-to-end-testing-in-angular-project-with-codeceptjs-ac1784de3420",target:"_blank",rel:"noopener noreferrer"}},[e._v("Setting up End-to-End Testing in Angular Project with CodeceptJS"),t("OutboundLink")],1),e._v(" post by Armno Prommarak.")]),e._v(" "),t("p",[e._v("This repository demonstrates usage of")]),e._v(" "),t("ul",[t("li",[e._v("Puppeteer helper")]),e._v(" "),t("li",[e._v("Working with Angular CLI")]),e._v(" "),t("li",[e._v("Reports with Mochawesome helper")])]),e._v(" "),t("h2",{attrs:{id:"rest-example-tests"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#rest-example-tests"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/PeterNgTr/codeceptjs-rest-demo",target:"_blank",rel:"noopener noreferrer"}},[e._v("REST Example Tests"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This repository demonstrates usage of")]),e._v(" "),t("ul",[t("li",[e._v("REST helper")])]),e._v(" "),t("h2",{attrs:{id:"automation-starter"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#automation-starter"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/sjorrillo/automation-starter",target:"_blank",rel:"noopener noreferrer"}},[e._v("Automation Starter"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("The purpose of this application is for learning the basics and how to use good practices and useful tools in automation.")]),e._v(" "),t("ul",[t("li",[e._v("Puppeteer helper")]),e._v(" "),t("li",[e._v("Working with gherkin, also it has type definitions and to be able to use them inside when, given and then make sure you add "),t("code",[e._v("declare function inject(): { I: CodeceptJS.I, [key: string]: any; };")]),e._v("in the "),t("code",[e._v("steps.d.ts")]),e._v("file")]),e._v(" "),t("li",[e._v("Linting "),t("code",[e._v("airbnb-base")]),e._v(", "),t("code",[e._v("codeceptjs/codeceptjs")]),e._v(" and full ES6 support")])]),e._v(" "),t("h2",{attrs:{id:"example-for-using-puppeteer-gherkin-allure-with-parallel-execution"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#example-for-using-puppeteer-gherkin-allure-with-parallel-execution"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/SchnuckySchuster/codeceptJSExample",target:"_blank",rel:"noopener noreferrer"}},[e._v("Example for using: Puppeteer, Gherkin, Allure with parallel execution"),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("This is a ready to use example that shows how to integrate CodeceptJS with Puppeteer and Allure as reporting tool.")]),e._v(" "),t("ul",[t("li",[e._v("detailed ReadMe")]),e._v(" "),t("li",[e._v("tests written in cucumber alongside tests written in the codeceptJS DSL")]),e._v(" "),t("li",[e._v("puppeteer helper example")]),e._v(" "),t("li",[e._v("test steps, pages, fragments")]),e._v(" "),t("li",[e._v("examples for sequential and parallel execution")]),e._v(" "),t("li",[e._v("generation of allure test results")])]),e._v(" "),t("h2",{attrs:{id:"example-for-advanced-rest-api-testing-typescript-axios-codeceptjs-jest-expect-docker-allure-mock-server-prettier-eslint-pre-commit-jest-unit-tests"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#example-for-advanced-rest-api-testing-typescript-axios-codeceptjs-jest-expect-docker-allure-mock-server-prettier-eslint-pre-commit-jest-unit-tests"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/EgorBodnar/rest-axios-codeceptjs-allure-docker-test-example",target:"_blank",rel:"noopener noreferrer"}},[e._v("Example for Advanced REST API testing: TypeScript, Axios, CodeceptJS, Jest Expect, Docker, Allure, Mock-Server, Prettier + Eslint, pre-commit, Jest Unit Tests "),t("OutboundLink")],1)]),e._v(" "),t("p",[e._v("One button example with built-in mocked backend.")]),e._v(" "),t("p",[e._v("If you already have a UI testing solution based on the CodeceptJS and you need to implement advanced REST API testing you can just extend your existing framework. Use this implementation as an example.\nThis is necessary if all integrations with TMS and CI/CD are already configured, and you do not want to reconnect and configure the plugins and libraries used for the new test runner. Use CodeceptJS!")]),e._v(" "),t("ul",[t("li",[e._v("Easy run")]),e._v(" "),t("li",[e._v("Detailed README")]),e._v(" "),t("li",[e._v("Well documented mocked backend's REST API endpoints")]),e._v(" "),t("li",[e._v("HTTP request client with session support and unit tests")]),e._v(" "),t("li",[e._v("Exemplary code control")]),e._v(" "),t("li",[e._v("Ready to launch in a CI/CD system as is")]),e._v(" "),t("li",[e._v("OOP, Test data models and builders, endpoint decorators")])]),e._v(" "),t("h2",{attrs:{id:"playwright-fun-with-codeceptjs"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#playwright-fun-with-codeceptjs"}},[e._v("#")]),e._v(" "),t("a",{attrs:{href:"https://github.com/PeterNgTr/codeceptjs-playwright-fun",target:"_blank",rel:"noopener noreferrer"}},[e._v("Playwright fun with CodeceptJS"),t("OutboundLink")],1)]),e._v(" "),t("ul",[t("li",[e._v("Tests are written in TS")]),e._v(" "),t("li",[e._v("CI/CD with Github Actions")]),e._v(" "),t("li",[e._v("Page Object Model is applied")]),e._v(" "),t("li",[e._v("ReportPortal Integration")])])])}),[],!1,null,null,null);t.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/51.392819f3.js b/assets/js/51.392819f3.js new file mode 100644 index 00000000..b037a962 --- /dev/null +++ b/assets/js/51.392819f3.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[51],{353:function(t,a,s){"use strict";s.r(a);var e=s(14),n=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h1",{attrs:{id:"self-healing-tests"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#self-healing-tests"}},[t._v("#")]),t._v(" Self-Healing Tests")]),t._v(" "),a("p",[t._v("Browser and Mobile tests can fail for vareity of reasons. However, on a big projects there are about 5-10 causes of flaky tests. The more you work and understand your end-to-end tests the more you learn patterns of failure. And after the research you understand how a test could have been fixed: to reload a page, to click that button once again, restart API request. If by looking into a failure you understand what, as a user, you would do to fix that error, then maybe you could teach your tests to heal themselves.")]),t._v(" "),a("h2",{attrs:{id:"what-is-healing"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#what-is-healing"}},[t._v("#")]),t._v(" What is Healing")]),t._v(" "),a("p",[a("strong",[t._v("Healing defines the way how a test reacts to failure")]),t._v(". You can define multiple healing recipes that could take all needed information: error message, failed test, step, page URL, HTML, etc. A healing recipe can perform some action to fix the failing test on the fly and continue its execution.")]),t._v(" "),a("p",[a("img",{attrs:{src:"/img/healing.png",alt:""}})]),t._v(" "),a("p",[t._v("Let's start with an example the most basic healing recipe. If after a click test has failed, try to reload page, and continue.")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[t._v("heal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipe")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'reload'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("priority")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("steps")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'click'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("fn")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("refreshPage")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Sure, this won't always work and probably won't be useful on every project. But let's follow the idea: if a click has failed, probably the button is not on a page, maybe it is an issue of rendering, maybe some other element overlapped our button, so if we try to reload page we can continue test execution. At least, this is what manual QA would do if they will run the following test in a browser. They will try to reload a page before reporting \"it has failed\".")]),t._v(" "),a("p",[t._v("So if it is a long end-2-end test that implements user journey, it is more valuable to continue its execution when possible, then fixing a minor issues like overlapping elements. Healing like this can improve the stability of a test.")]),t._v(" "),a("p",[t._v("The example above is only one way a test can be healed. But you can define as many heal recipes as you like. What heal recipe would be effective in your case is depends on a system you test, so "),a("strong",[t._v("there are no pre-defined heal recipes")]),t._v(".")]),t._v(" "),a("h2",{attrs:{id:"healing-patterns"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#healing-patterns"}},[t._v("#")]),t._v(" Healing Patterns")]),t._v(" "),a("p",[t._v("There are some ideas where healing can be useful to you:")]),t._v(" "),a("ul",[a("li",[a("strong",[t._v("Networking")]),t._v(". If a test depends on a remote resource, and fails because this resource is not available, you may try to send API request to restore that resource before throwing an error.")]),t._v(" "),a("li",[a("strong",[t._v("Data Consistency")]),t._v(". A test may fail because you noticed the data glitch in a system. Instead of failing a test you may try to clean up the data and try again to proceed.")]),t._v(" "),a("li",[a("strong",[t._v("UI Change")]),t._v(". If there is a planned UI migration of a component, for instance Button was changed to Dropdown. You can prepare test so if it fails clicking Button it can try to do so with Dropdown.")]),t._v(" "),a("li",[a("strong",[t._v("Do it again")]),t._v(". If you know, that going one step back and trying to do same actions may solve the issue, you can do so from healers. For instance, a modal didn't render correctly, so you can close it and try to click to open it again.")])]),t._v(" "),a("h2",{attrs:{id:"healing-vs-retries"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#healing-vs-retries"}},[t._v("#")]),t._v(" Healing vs Retries")]),t._v(" "),a("p",[t._v("Unlike retries heal recipes has following benefits:")]),t._v(" "),a("ul",[a("li",[t._v("Heal recipes are "),a("strong",[t._v("declarative")]),t._v(", they are not added directly into into the test code. This keeps test clean and scenario-focused,")]),t._v(" "),a("li",[t._v("Retry can only re-run failed step(s), but heal recipe can "),a("strong",[t._v("perform wide set of actions")])]),t._v(" "),a("li",[t._v("Heal recipe "),a("strong",[t._v("can react to any step of any test")]),t._v(". So if you catch a common error and you can heal it, you won't need to guess where it can be thrown.")])]),t._v(" "),a("h2",{attrs:{id:"how-to-start-healing"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#how-to-start-healing"}},[t._v("#")]),t._v(" How to Start Healing")]),t._v(" "),a("p",[t._v("To enable healing, you need to define healing recipes and enable heal plugin.")]),t._v(" "),a("p",[t._v("Create basic healing recipes using this command:")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v("npx codeceptjs generate:heal\n")])])]),a("p",[t._v("or")]),t._v(" "),a("div",{staticClass:"language- extra-class"},[a("pre",{pre:!0,attrs:{class:"language-text"}},[a("code",[t._v("npx codeceptjs gr\n")])])]),a("p",[t._v("this will generate "),a("code",[t._v("recipes.js")]),t._v(" (or "),a("code",[t._v("recipes.ts")]),t._v(") in the root directory. Provided default recipe include "),a("a",{attrs:{href:"#ai-healing"}},[t._v("AI healing")]),t._v(" and "),a("code",[t._v("clickAndType")]),t._v(" recipe that replaces "),a("code",[t._v("fillField")]),t._v(" with "),a("code",[t._v("click")]),t._v("+"),a("code",[t._v("type")]),t._v(". Use them as examples to write your own heal recipes that will fit for application you are testing.")]),t._v(" "),a("p",[t._v("Require "),a("code",[t._v("recipes")]),t._v(" file and add "),a("code",[t._v("heal")]),t._v(" plugin to "),a("code",[t._v("codecept.conf")]),t._v(" file:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[t._v("\n"),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./heal'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\nexports"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("config "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("plugins")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("heal")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("enabled")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("blockquote",[a("p",[t._v("Please note that, healing has no sense while developing tests, so it won't work in "),a("code",[t._v("--debug")]),t._v(" mode.")])]),t._v(" "),a("h2",{attrs:{id:"writing-recipes"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#writing-recipes"}},[t._v("#")]),t._v(" Writing Recipes")]),t._v(" "),a("p",[t._v("Custom heal recipes can be added by running "),a("code",[t._v("heal.addRecipe()")]),t._v(" function. By default it should be added to "),a("code",[t._v("recipes.js")]),t._v(" (or "),a("code",[t._v("recipes.ts")]),t._v(") file.")]),t._v(" "),a("p",[t._v("Let's see what recipe consist of:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[t._v("heal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipe")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'reloadPageOnUserAccount'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// recipe priority")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// which recipe should be tried first ")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("priority")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// an array of steps which may cause the error")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// after which a recipe should be activate")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("steps")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'click'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// if you need some additional information like URL of a page,")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// or its HTML, you can add this context to healing function by ")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// defining `prepare` list of variable")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("prepare")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("url")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabCurrentUrl")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("html")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabHTMLFrom")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'body'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// don't add variables that you won't use inside the recipe")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// probably we want to execute recipes only on some tests")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// so you can set a string or regex which will check if a test title matches the name")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// in this case we execute recipe only on tests that have "@flaky" in their name')]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("grep")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@flaky'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// function to launch healing process ")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("fn")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" \n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// standard context variables")]),t._v("\n step"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" test"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" error"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" prevSteps"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// variables coming from prepare function")]),t._v("\n html"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" url"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n \n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" stepArgs "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" step"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("args"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// at this point we can decide, should we provide a healing recipe or not")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// for instance, if URL is not the one we can heal at, we should not provide any recipes")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("if")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("!")]),t._v("url"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("includes")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/user/acccount'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// otherwise we return a function that will be executed")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// this is a very basic example action")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// probably you should do something more sophisticated")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// to heal the test")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("reloadPage")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("wait")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" \n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Let's briefly sum up the properties of a recipe:")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("grep")]),t._v(" - selects tests by their name to apply heal to")]),t._v(" "),a("li",[a("code",[t._v("steps")]),t._v(" - defines on which steps a recipe should react")]),t._v(" "),a("li",[a("code",[t._v("priority")]),t._v(" - sets the order of recipes being applied")]),t._v(" "),a("li",[a("code",[t._v("prepare")]),t._v(" - declare variables from a context, which can be used for healing")]),t._v(" "),a("li",[a("code",[t._v("fn")]),t._v(" - a function to be applied for healing. It takes all context params: "),a("code",[t._v("test")]),t._v(", "),a("code",[t._v("step")]),t._v(", "),a("code",[t._v("error")]),t._v(", "),a("code",[t._v("prevSteps")]),t._v(" and returns return either a function or a markdown text with recipes (used by AI healers). If no recipes match the context should not return anything;")])]),t._v(" "),a("h2",{attrs:{id:"ai-healing"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#ai-healing"}},[t._v("#")]),t._v(" AI Healing")]),t._v(" "),a("p",[t._v("AI can be used to heal failed tests. Large Language Models can analyze HTML of a failed test and provide a suggestion what actions should be performed instead. This can be helpful when running tests on CI as AI can make basic decisions to stabilize failing tests.")]),t._v(" "),a("blockquote",[a("p",[t._v("Use "),a("strong",[t._v("OpenAI, Azure OpenAI, Claude")]),t._v(", or any of other LLM that can take a prompt, analyze request and provide valid JS code which can be executed by CodeceptJS as a healing suggestion.")])]),t._v(" "),a("p",[t._v("AI healing recipe is created within "),a("code",[t._v("recipes.js")]),t._v(" file:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[t._v("heal"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("addRecipe")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'ai'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("priority")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("prepare")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("html")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabHTMLFrom")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'body'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("steps")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'click'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'fillField'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'appendField'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'selectOption'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'attachFile'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'checkOption'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'uncheckOption'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'doubleClick'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("fn")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("args")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" ai"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("healFailedStep")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("args"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("As you use, it will be activated on failed steps and will use HTML of a page as additional information. The prompt, error, and the HTML will be sent to AI provider you configured.")]),t._v(" "),a("p",[t._v("Learn more how you can "),a("a",{attrs:{href:"./ai"}},[t._v("configure AI provider")]),t._v(".")]),t._v(" "),a("p",[t._v("To activate the AI healer don't forget to run tests with "),a("code",[t._v("--ai")]),t._v(" flag.")])])}),[],!1,null,null,null);a.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/52.7edb483c.js b/assets/js/52.7edb483c.js new file mode 100644 index 00000000..3343ffcb --- /dev/null +++ b/assets/js/52.7edb483c.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[52],{371:function(e,t,r){"use strict";r.r(t);var a=r(14),s=Object(a.a)({},(function(){var e=this,t=e._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":e.$parent.slotKey}},[t("h2",{attrs:{id:"ai"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#ai"}},[e._v("#")]),e._v(" AI")]),e._v(" "),t("p",[t("strong",[e._v("Extends Helper")])]),e._v(" "),t("p",[e._v("AI Helper for CodeceptJS.")]),e._v(" "),t("p",[e._v("This helper class provides integration with the AI GPT-3.5 or 4 language model for generating responses to questions or prompts within the context of web pages. It allows you to interact with the GPT-3.5 model to obtain intelligent responses based on HTML fragments or general prompts.\nThis helper should be enabled with any web helpers like Playwright or Puppeteer or WebDrvier to ensure the HTML context is available.")]),e._v(" "),t("p",[e._v("Use it only in development mode. It is recommended to run it only inside pause() mode.")]),e._v(" "),t("h2",{attrs:{id:"configuration"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#configuration"}},[e._v("#")]),e._v(" Configuration")]),e._v(" "),t("p",[e._v("This helper should be configured in codecept.json or codecept.conf.js")]),e._v(" "),t("ul",[t("li",[t("code",[e._v("chunkSize")]),e._v(": - The maximum number of characters to send to the AI API at once. We split HTML fragments by 8000 chars to not exceed token limit. Increase this value if you use GPT-4.")])]),e._v(" "),t("h3",{attrs:{id:"parameters"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#parameters"}},[e._v("#")]),e._v(" Parameters")]),e._v(" "),t("ul",[t("li",[t("code",[e._v("config")])])]),e._v(" "),t("h3",{attrs:{id:"askforpageobject"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#askforpageobject"}},[e._v("#")]),e._v(" askForPageObject")]),e._v(" "),t("p",[e._v("Generates PageObject for current page using AI.")]),e._v(" "),t("p",[e._v("It saves the PageObject to the output directory. You can review the page object and adjust it as needed and move to pages directory.\nPrompt can be customized in a global config file.")]),e._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// create page object for whole page")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token constant"}},[e._v("I")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("askForPageObject")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'home'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// create page object with extra prompt")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token constant"}},[e._v("I")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("askForPageObject")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'home'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'implement signIn(username, password) method'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[e._v("// create page object for a specific element")]),e._v("\n"),t("span",{pre:!0,attrs:{class:"token constant"}},[e._v("I")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("askForPageObject")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'home'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[e._v("null")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'.detail'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n")])])]),t("p",[e._v("Asks for a page object based on the provided page name, locator, and extra prompt.")]),e._v(" "),t("h4",{attrs:{id:"parameters-2"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#parameters-2"}},[e._v("#")]),e._v(" Parameters")]),e._v(" "),t("ul",[t("li",[t("code",[e._v("pageName")]),e._v(" "),t("strong",[t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[e._v("string"),t("OutboundLink")],1)]),e._v(" The name of the page to retrieve the object for.")]),e._v(" "),t("li",[t("code",[e._v("extraPrompt")]),e._v(" "),t("strong",[e._v("("),t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[e._v("string"),t("OutboundLink")],1),e._v(" | null)")]),e._v(" An optional extra prompt for additional context or information.")]),e._v(" "),t("li",[t("code",[e._v("locator")]),e._v(" "),t("strong",[e._v("("),t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[e._v("string"),t("OutboundLink")],1),e._v(" | null)")]),e._v(" An optional locator to find a specific element on the page.")])]),e._v(" "),t("p",[e._v("Returns "),t("strong",[t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[e._v("Promise"),t("OutboundLink")],1),e._v("<"),t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[e._v("Object"),t("OutboundLink")],1),e._v(">")]),e._v(" A promise that resolves to the requested page object.")]),e._v(" "),t("h3",{attrs:{id:"askgptgeneralprompt"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#askgptgeneralprompt"}},[e._v("#")]),e._v(" askGptGeneralPrompt")]),e._v(" "),t("p",[e._v("Send a general request to AI and return response.")]),e._v(" "),t("h4",{attrs:{id:"parameters-3"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#parameters-3"}},[e._v("#")]),e._v(" Parameters")]),e._v(" "),t("ul",[t("li",[t("code",[e._v("prompt")]),e._v(" "),t("strong",[t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[e._v("string"),t("OutboundLink")],1)])])]),e._v(" "),t("p",[e._v("Returns "),t("strong",[t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[e._v("Promise"),t("OutboundLink")],1),e._v("<"),t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[e._v("string"),t("OutboundLink")],1),e._v(">")]),e._v(" A Promise that resolves to the generated response from the GPT model.")]),e._v(" "),t("h3",{attrs:{id:"askgptonpage"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#askgptonpage"}},[e._v("#")]),e._v(" askGptOnPage")]),e._v(" "),t("p",[e._v("Asks the AI GPT language model a question based on the provided prompt within the context of the current page's HTML.")]),e._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token constant"}},[e._v("I")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("askGptOnPage")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'what does this page do?'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n")])])]),t("h4",{attrs:{id:"parameters-4"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#parameters-4"}},[e._v("#")]),e._v(" Parameters")]),e._v(" "),t("ul",[t("li",[t("code",[e._v("prompt")]),e._v(" "),t("strong",[t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[e._v("string"),t("OutboundLink")],1)]),e._v(" The question or prompt to ask the GPT model.")])]),e._v(" "),t("p",[e._v("Returns "),t("strong",[t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[e._v("Promise"),t("OutboundLink")],1),e._v("<"),t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[e._v("string"),t("OutboundLink")],1),e._v(">")]),e._v(" A Promise that resolves to the generated responses from the GPT model, joined by newlines.")]),e._v(" "),t("h3",{attrs:{id:"askgptonpagefragment"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#askgptonpagefragment"}},[e._v("#")]),e._v(" askGptOnPageFragment")]),e._v(" "),t("p",[e._v("Asks the AI a question based on the provided prompt within the context of a specific HTML fragment on the current page.")]),e._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token constant"}},[e._v("I")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[e._v("askGptOnPageFragment")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'describe features of this screen'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(",")]),e._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[e._v("'.screen'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[e._v(";")]),e._v("\n")])])]),t("h4",{attrs:{id:"parameters-5"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#parameters-5"}},[e._v("#")]),e._v(" Parameters")]),e._v(" "),t("ul",[t("li",[t("code",[e._v("prompt")]),e._v(" "),t("strong",[t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[e._v("string"),t("OutboundLink")],1)]),e._v(" The question or prompt to ask the GPT-3.5 model.")]),e._v(" "),t("li",[t("code",[e._v("locator")]),e._v(" "),t("strong",[t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[e._v("string"),t("OutboundLink")],1)]),e._v(" The locator or selector used to identify the HTML fragment on the page.")])]),e._v(" "),t("p",[e._v("Returns "),t("strong",[t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[e._v("Promise"),t("OutboundLink")],1),e._v("<"),t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[e._v("string"),t("OutboundLink")],1),e._v(">")]),e._v(" A Promise that resolves to the generated response from the GPT model.")])])}),[],!1,null,null,null);t.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/53.64f7b490.js b/assets/js/53.64f7b490.js new file mode 100644 index 00000000..313b4cbb --- /dev/null +++ b/assets/js/53.64f7b490.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[53],{352:function(t,s,a){"use strict";a.r(s);var e=a(14),n=Object(e.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"apidatafactory"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#apidatafactory"}},[t._v("#")]),t._v(" ApiDataFactory")]),t._v(" "),s("p",[s("strong",[t._v("Extends Helper")])]),t._v(" "),s("p",[t._v("Helper for managing remote data using REST API.\nUses data generators like "),s("a",{attrs:{href:"https://github.com/rosiejs/rosie",target:"_blank",rel:"noopener noreferrer"}},[t._v("rosie"),s("OutboundLink")],1),t._v(" or factory girl to create new record.")]),t._v(" "),s("p",[t._v("By defining a factory you set the rules of how data is generated.\nThis data will be saved on server via REST API and deleted in the end of a test.")]),t._v(" "),s("h2",{attrs:{id:"use-case"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#use-case"}},[t._v("#")]),t._v(" Use Case")]),t._v(" "),s("p",[t._v("Acceptance tests interact with a websites using UI and real browser.\nThere is no way to create data for a specific test other than from user interface.\nThat makes tests slow and fragile. Instead of testing a single feature you need to follow all creation/removal process.")]),t._v(" "),s("p",[t._v("This helper solves this problem.\nMost of web application have API, and it can be used to create and delete test records.\nBy combining REST API with Factories you can easily create records for tests:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("have")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("login")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("email")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert@mail.com'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" id "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("have")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'post'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("title")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'My first post'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("haveMultiple")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'comment'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("post_id")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" id"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("To make this work you need")]),t._v(" "),s("ol",[s("li",[t._v("REST API endpoint which allows to perform create / delete requests and")]),t._v(" "),s("li",[t._v("define data generation rules")])]),t._v(" "),s("h3",{attrs:{id:"setup"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#setup"}},[t._v("#")]),t._v(" Setup")]),t._v(" "),s("p",[t._v("Install "),s("a",{attrs:{href:"https://github.com/rosiejs/rosie",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rosie"),s("OutboundLink")],1),t._v(" and "),s("a",{attrs:{href:"https://www.npmjs.com/package/faker",target:"_blank",rel:"noopener noreferrer"}},[t._v("Faker"),s("OutboundLink")],1),t._v(" libraries.")]),t._v(" "),s("div",{staticClass:"language-sh extra-class"},[s("pre",{pre:!0,attrs:{class:"language-sh"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function"}},[t._v("npm")]),t._v(" i rosie @faker-js/faker --save-dev\n")])])]),s("p",[t._v("Create a factory file for a resource.")]),t._v(" "),s("p",[t._v("See the example for Posts factories:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// tests/factories/posts.js")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" Factory "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'rosie'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" faker "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@faker-js/faker'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\nmodule"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("exports "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Factory")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// no need to set id, it will be set by REST API")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("attr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'author'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" faker"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("findName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("attr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'title'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" faker"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("lorem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sentence")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("attr")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'body'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" faker"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("lorem"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("paragraph")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("For more options see "),s("a",{attrs:{href:"https://github.com/rosiejs/rosie",target:"_blank",rel:"noopener noreferrer"}},[t._v("rosie documentation"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("p",[t._v("Then configure ApiDataHelper to match factories and REST API:")]),t._v(" "),s("h3",{attrs:{id:"configuration"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#configuration"}},[t._v("#")]),t._v(" Configuration")]),t._v(" "),s("p",[t._v("ApiDataFactory has following config options:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("endpoint")]),t._v(": base URL for the API to send requests to.")]),t._v(" "),s("li",[s("code",[t._v("cleanup")]),t._v(" (default: true): should inserted records be deleted up after tests")]),t._v(" "),s("li",[s("code",[t._v("factories")]),t._v(": list of defined factories")]),t._v(" "),s("li",[s("code",[t._v("returnId")]),t._v(" (default: false): return id instead of a complete response when creating items.")]),t._v(" "),s("li",[s("code",[t._v("headers")]),t._v(": list of headers")]),t._v(" "),s("li",[s("code",[t._v("REST")]),t._v(": configuration for REST requests")])]),t._v(" "),s("p",[t._v("See the example:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ApiDataFactory")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("endpoint")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://user.com/api"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("cleanup")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("headers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Content-Type'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'application/json'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Accept'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'application/json'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("factories")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("post")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("uri")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/posts"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("factory")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./factories/post"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("comment")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("factory")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./factories/comment"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("create")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("post")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/comments/create"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("delete")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("post")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/comments/delete/{id}"')]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("fetchId")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("It is required to set REST API "),s("code",[t._v("endpoint")]),t._v(" which is the baseURL for all API requests.\nFactory file is expected to be passed via "),s("code",[t._v("factory")]),t._v(" option.")]),t._v(" "),s("p",[t._v("This Helper uses "),s("a",{attrs:{href:"http://codecept.io/helpers/REST/",target:"_blank",rel:"noopener noreferrer"}},[t._v("REST"),s("OutboundLink")],1),t._v(' helper and accepts its configuration in "REST" section.\nFor instance, to set timeout you should add:')]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"ApiDataFactory"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"REST"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"timeout"')]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"100000"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"requests"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#requests"}},[t._v("#")]),t._v(" Requests")]),t._v(" "),s("p",[t._v("By default to create a record ApiDataFactory will use endpoint and plural factory name:")]),t._v(" "),s("ul",[s("li",[t._v("create: "),s("code",[t._v("POST {endpoint}/{resource} data")])]),t._v(" "),s("li",[t._v("delete: "),s("code",[t._v("DELETE {endpoint}/{resource}/id")])])]),t._v(" "),s("p",[t._v("Example ("),s("code",[t._v("endpoint")]),t._v(": "),s("code",[t._v("http://app.com/api")]),t._v("):")]),t._v(" "),s("ul",[s("li",[t._v("create: POST request to "),s("code",[t._v("http://app.com/api/users")])]),t._v(" "),s("li",[t._v("delete: DELETE request to "),s("code",[t._v("http://app.com/api/users/1")])])]),t._v(" "),s("p",[t._v("This behavior can be configured with following options:")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("uri")]),t._v(": set different resource uri. Example: "),s("code",[t._v("uri: account")]),t._v(" => "),s("code",[t._v("http://app.com/api/account")]),t._v(".")]),t._v(" "),s("li",[s("code",[t._v("create")]),t._v(": override create options. Expected format: "),s("code",[t._v("{ method: uri }")]),t._v(". Example: "),s("code",[t._v('{ "post": "/users/create" }')])]),t._v(" "),s("li",[s("code",[t._v("delete")]),t._v(": override delete options. Expected format: "),s("code",[t._v("{ method: uri }")]),t._v(". Example: "),s("code",[t._v('{ "post": "/users/delete/{id}" }')])])]),t._v(" "),s("p",[t._v("Requests can also be overridden with a function which returns "),s("a",{attrs:{href:"https://github.com/axios/axios#request-config",target:"_blank",rel:"noopener noreferrer"}},[t._v("axois request config"),s("OutboundLink")],1),t._v(".")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("create")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("method")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'post'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/posts'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" data "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("delete")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("method")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'delete'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/posts'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("data")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" id "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("p",[t._v("Requests can be updated on the fly by using "),s("code",[t._v("onRequest")]),t._v(" function. For instance, you can pass in current session from a cookie.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("onRequest")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("request")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// using global codeceptjs instance")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" cookie "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" codeceptjs"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("container"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'WebDriver'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabCookie")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'session'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n request"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headers "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Cookie")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token template-string"}},[s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("session=")]),s("span",{pre:!0,attrs:{class:"token interpolation"}},[s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("cookie"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),s("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),s("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h3",{attrs:{id:"responses"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#responses"}},[t._v("#")]),t._v(" Responses")]),t._v(" "),s("p",[t._v("By default "),s("code",[t._v("I.have()")]),t._v(" returns a promise with a created data:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" client "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("have")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'client'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Ids of created records are collected and used in the end of a test for the cleanup.\nIf you need to receive "),s("code",[t._v("id")]),t._v(" instead of full response enable "),s("code",[t._v("returnId")]),t._v(" in a helper config:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// returnId: false")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" clientId "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("have")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'client'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// clientId == 1")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// returnId: true")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" clientId "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("have")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'client'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// client == { name: 'John', email: 'john@snow.com' }")]),t._v("\n")])])]),s("p",[t._v("By default "),s("code",[t._v("id")]),t._v(" property of response is taken. This behavior can be changed by setting "),s("code",[t._v("fetchId")]),t._v(" function in a factory config.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("factories")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("post")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("uri")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"/posts"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("factory")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v('"./factories/post"')]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("fetchId")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("data")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" data"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("result"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("posts"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h2",{attrs:{id:"methods"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#methods"}},[t._v("#")]),t._v(" Methods")]),t._v(" "),s("h3",{attrs:{id:"parameters"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#parameters"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("config")])])]),t._v(" "),s("h3",{attrs:{id:"requestcreate"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#requestcreate"}},[t._v("#")]),t._v(" _requestCreate")]),t._v(" "),s("p",[t._v("Executes request to create a record in API.\nCan be replaced from a in custom helper.")]),t._v(" "),s("h4",{attrs:{id:"parameters-2"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#parameters-2"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("factory")]),t._v(" "),s("strong",[t._v("any")])]),t._v(" "),s("li",[s("code",[t._v("data")]),t._v(" "),s("strong",[t._v("any")])])]),t._v(" "),s("h3",{attrs:{id:"requestdelete"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#requestdelete"}},[t._v("#")]),t._v(" _requestDelete")]),t._v(" "),s("p",[t._v("Executes request to delete a record in API\nCan be replaced from a custom helper.")]),t._v(" "),s("h4",{attrs:{id:"parameters-3"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#parameters-3"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("factory")]),t._v(" "),s("strong",[t._v("any")])]),t._v(" "),s("li",[s("code",[t._v("id")]),t._v(" "),s("strong",[t._v("any")])])]),t._v(" "),s("h3",{attrs:{id:"have"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#have"}},[t._v("#")]),t._v(" have")]),t._v(" "),s("p",[t._v("Generates a new record using factory and saves API request to store it.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a user")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("have")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create user with defined email")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// and receive it when inside async function")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" user "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("have")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("email")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user@user.com'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a user with options that will not be included in the final request")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("have")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("age")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("33")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("height")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("55")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("h4",{attrs:{id:"parameters-4"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#parameters-4"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("factory")]),t._v(" "),s("strong",[t._v("any")]),t._v(" factory to use")]),t._v(" "),s("li",[s("code",[t._v("params")]),t._v(" "),s("strong",[t._v("any?")]),t._v(" predefined parameters")]),t._v(" "),s("li",[s("code",[t._v("options")]),t._v(" "),s("strong",[t._v("any?")]),t._v(" options for programmatically generate the attributes")])]),t._v(" "),s("p",[t._v("Returns "),s("strong",[s("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),s("OutboundLink")],1),t._v("")])]),t._v(" "),s("h3",{attrs:{id:"havemultiple"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#havemultiple"}},[t._v("#")]),t._v(" haveMultiple")]),t._v(" "),s("p",[t._v("Generates bunch of records and saves multiple API requests to store them.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create 3 posts")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("haveMultiple")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'post'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create 3 posts by one author")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("haveMultiple")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'post'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("author")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create 3 posts by one author with options")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("haveMultiple")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'post'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("author")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("publish_date")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'01.01.1997'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h4",{attrs:{id:"parameters-5"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#parameters-5"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("factory")]),t._v(" "),s("strong",[t._v("any")])]),t._v(" "),s("li",[s("code",[t._v("times")]),t._v(" "),s("strong",[t._v("any")])]),t._v(" "),s("li",[s("code",[t._v("params")]),t._v(" "),s("strong",[t._v("any?")])]),t._v(" "),s("li",[s("code",[t._v("options")]),t._v(" "),s("strong",[t._v("any?")])])])])}),[],!1,null,null,null);s.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/54.199740eb.js b/assets/js/54.199740eb.js new file mode 100644 index 00000000..a98bb978 --- /dev/null +++ b/assets/js/54.199740eb.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[54],{356:function(t,e,a){"use strict";a.r(e);var s=a(14),r=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"appium"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#appium"}},[t._v("#")]),t._v(" Appium")]),t._v(" "),e("p",[e("strong",[t._v("Extends Webdriver")])]),t._v(" "),e("p",[t._v("Appium helper extends "),e("a",{attrs:{href:"http://codecept.io/helpers/WebDriver/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Webdriver"),e("OutboundLink")],1),t._v(" helper.\nIt supports all browser methods and also includes special methods for mobile apps testing.\nYou can use this helper to test Web on desktop and mobile devices and mobile apps.")]),t._v(" "),e("h2",{attrs:{id:"appium-installation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#appium-installation"}},[t._v("#")]),t._v(" Appium Installation")]),t._v(" "),e("p",[t._v("Appium is an open source test automation framework for use with native, hybrid and mobile web apps that implements the WebDriver protocol.\nIt allows you to run Selenium tests on mobile devices and also test native, hybrid and mobile web apps.")]),t._v(" "),e("p",[t._v("Download and install "),e("a",{attrs:{href:"https://appium.io/docs/en/2.1/",target:"_blank",rel:"noopener noreferrer"}},[t._v("Appium"),e("OutboundLink")],1)]),t._v(" "),e("div",{staticClass:"language-sh extra-class"},[e("pre",{pre:!0,attrs:{class:"language-sh"}},[e("code",[e("span",{pre:!0,attrs:{class:"token function"}},[t._v("npm")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("install")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token parameter variable"}},[t._v("-g")]),t._v(" appium\n")])])]),e("p",[t._v("Launch the daemon: "),e("code",[t._v("appium")])]),t._v(" "),e("h2",{attrs:{id:"helper-configuration"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#helper-configuration"}},[t._v("#")]),t._v(" Helper configuration")]),t._v(" "),e("p",[t._v("This helper should be configured in codecept.conf.ts or codecept.conf.js")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("appiumV2")]),t._v(": set this to true if you want to run tests with AppiumV2. See more how to setup "),e("a",{attrs:{href:"https://codecept.io/mobile/#setting-up",target:"_blank",rel:"noopener noreferrer"}},[t._v("here"),e("OutboundLink")],1)]),t._v(" "),e("li",[e("code",[t._v("app")]),t._v(": Application path. Local path or remote URL to an .ipa or .apk file, or a .zip containing one of these. Alias to desiredCapabilities.appPackage")]),t._v(" "),e("li",[e("code",[t._v("host")]),t._v(": (default: 'localhost') Appium host")]),t._v(" "),e("li",[e("code",[t._v("port")]),t._v(": (default: '4723') Appium port")]),t._v(" "),e("li",[e("code",[t._v("platform")]),t._v(": (Android or IOS), which mobile OS to use; alias to desiredCapabilities.platformName")]),t._v(" "),e("li",[e("code",[t._v("restart")]),t._v(": restart browser or app between tests (default: true), if set to false cookies will be cleaned but browser window will be kept and for apps nothing will be changed.")]),t._v(" "),e("li",[e("code",[t._v("desiredCapabilities")]),t._v(": [], Appium capabilities, see below\n"),e("ul",[e("li",[e("code",[t._v("platformName")]),t._v(" - Which mobile OS platform to use")]),t._v(" "),e("li",[e("code",[t._v("appPackage")]),t._v(" - Java package of the Android app you want to run")]),t._v(" "),e("li",[e("code",[t._v("appActivity")]),t._v(" - Activity name for the Android activity you want to launch from your package.")]),t._v(" "),e("li",[e("code",[t._v("deviceName")]),t._v(": The kind of mobile device or emulator to use")]),t._v(" "),e("li",[e("code",[t._v("platformVersion")]),t._v(": Mobile OS version")]),t._v(" "),e("li",[e("code",[t._v("app")]),t._v(" - The absolute local path or remote http URL to an .ipa or .apk file, or a .zip containing one of these. Appium will attempt to install this app binary on the appropriate device first.")]),t._v(" "),e("li",[e("code",[t._v("browserName")]),t._v(": Name of mobile web browser to automate. Should be an empty string if automating an app instead.")])])])]),t._v(" "),e("p",[t._v("Example Android App:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Appium")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("platform")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"Android"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("desiredCapabilities")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("appPackage")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.example.android.myApp"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("appActivity")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"MainActivity"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("deviceName")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"OnePlus3"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("platformVersion")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"6.0.1"')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("Example iOS Mobile Web with local Appium:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Appium")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("platform")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"iOS"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"https://the-internet.herokuapp.com/"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("desiredCapabilities")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("deviceName")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"iPhone X"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("platformVersion")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"12.0"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browserName")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"safari"')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("Example iOS Mobile Web on BrowserStack:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Appium")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("host")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"hub-cloud.browserstack.com"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("port")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("4444")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" process"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("BROWSERSTACK_USER")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("key")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" process"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("BROWSERSTACK_KEY")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("platform")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"iOS"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("url")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"https://the-internet.herokuapp.com/"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("desiredCapabilities")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("realMobile")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"true"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("device")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"iPhone 8"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("os_version")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"12"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browserName")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"safari"')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("Example Android App using AppiumV2 on BrowserStack:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Appium")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("appiumV2")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("host")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"hub-cloud.browserstack.com"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("port")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("4444")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" process"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("BROWSERSTACK_USER")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("key")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" process"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("BROWSERSTACK_KEY")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("app")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token template-string"}},[e("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("bs://c700ce60cf1gjhgjh3ae8ed9770ghjg5a55b8e022f13c5827cg")]),e("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("browser")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("desiredCapabilities")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'appPackage'")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" data"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("packageName"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'deviceName'")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" process"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("DEVICE")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Google Pixel 3'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'platformName'")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" process"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("PLATFORM")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'android'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'platformVersion'")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" process"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("OS_VERSION")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'10.0'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'automationName'")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" process"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("ENGINE")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'UIAutomator2'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'newCommandTimeout'")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("300000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'androidDeviceReadyTimeout'")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("300000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'androidInstallTimeout'")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("90000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'appWaitDuration'")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("300000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'autoGrantPermissions'")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'gpsEnabled'")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'isHeadless'")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'noReset'")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'noSign'")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'bstack:options'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"appiumVersion"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"2.0.1"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("Additional configuration params can be used from "),e("a",{attrs:{href:"https://github.com/appium/appium/blob/master/packages/appium/docs/en/guides/caps.md",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://github.com/appium/appium/blob/master/packages/appium/docs/en/guides/caps.md"),e("OutboundLink")],1)]),t._v(" "),e("h2",{attrs:{id:"access-from-helpers"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#access-from-helpers"}},[t._v("#")]),t._v(" Access From Helpers")]),t._v(" "),e("p",[t._v("Receive Appium client from a custom helper by accessing "),e("code",[t._v("browser")]),t._v(" property:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" browser "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helpers"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Appium'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("browser\n")])])]),e("h2",{attrs:{id:"methods"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#methods"}},[t._v("#")]),t._v(" Methods")]),t._v(" "),e("h3",{attrs:{id:"parameters"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("config")])])]),t._v(" "),e("h3",{attrs:{id:"runonios"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#runonios"}},[t._v("#")]),t._v(" runOnIOS")]),t._v(" "),e("p",[t._v("Execute code only on iOS")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("runOnIOS")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'//UIAApplication[1]/UIAWindow[1]/UIAButton[1]'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hi, IOS'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~welcome'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Additional filter can be applied by checking for capabilities.\nFor instance, this code will be executed only on iPhone 5s:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("runOnIOS")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("deviceName")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'iPhone 5s'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Also capabilities can be checked by a function.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("runOnAndroid")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("caps")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// caps is current config of desiredCapabiliites")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" caps"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("platformVersion "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("6")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-2"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("caps")]),t._v(" "),e("strong",[t._v("any")])]),t._v(" "),e("li",[e("code",[t._v("fn")]),t._v(" "),e("strong",[t._v("any")])])]),t._v(" "),e("h3",{attrs:{id:"runonandroid"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#runonandroid"}},[t._v("#")]),t._v(" runOnAndroid")]),t._v(" "),e("p",[t._v("Execute code only on Android")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("runOnAndroid")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'io.selendroid.testapp:id/buttonTest'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Additional filter can be applied by checking for capabilities.\nFor instance, this code will be executed only on Android 6.0:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("runOnAndroid")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("platformVersion")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'6.0'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Also capabilities can be checked by a function.\nIn this case, code will be executed only on Android >= 6.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("runOnAndroid")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("caps")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// caps is current config of desiredCapabiliites")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" caps"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("platformVersion "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(">=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("6")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// ...")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-3"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("caps")]),t._v(" "),e("strong",[t._v("any")])]),t._v(" "),e("li",[e("code",[t._v("fn")]),t._v(" "),e("strong",[t._v("any")])])]),t._v(" "),e("h3",{attrs:{id:"runinweb"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#runinweb"}},[t._v("#")]),t._v(" runInWeb")]),t._v(" "),e("p",[t._v("Execute code only in Web mode.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("runInWeb")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForElement")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#data'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeInCurrentUrl")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/data'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-4"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("fn")]),t._v(" "),e("strong",[t._v("any")])])]),t._v(" "),e("h3",{attrs:{id:"checkifappisinstalled"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#checkifappisinstalled"}},[t._v("#")]),t._v(" checkIfAppIsInstalled")]),t._v(" "),e("p",[t._v("Returns app installation status.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("checkIfAppIsInstalled")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.example.android.apis"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-5"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("bundleId")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" String ID of bundled app")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("<"),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean",target:"_blank",rel:"noopener noreferrer"}},[t._v("boolean"),e("OutboundLink")],1),t._v(">")]),t._v(" Appium: support only Android")]),t._v(" "),e("h3",{attrs:{id:"seeappisinstalled"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#seeappisinstalled"}},[t._v("#")]),t._v(" seeAppIsInstalled")]),t._v(" "),e("p",[t._v("Check if an app is installed.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeAppIsInstalled")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.example.android.apis"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-6"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-6"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("bundleId")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" String ID of bundled app")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support only Android")]),t._v(" "),e("h3",{attrs:{id:"seeappisnotinstalled"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#seeappisnotinstalled"}},[t._v("#")]),t._v(" seeAppIsNotInstalled")]),t._v(" "),e("p",[t._v("Check if an app is not installed.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeAppIsNotInstalled")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"com.example.android.apis"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-7"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-7"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("bundleId")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" String ID of bundled app")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support only Android")]),t._v(" "),e("h3",{attrs:{id:"installapp"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#installapp"}},[t._v("#")]),t._v(" installApp")]),t._v(" "),e("p",[t._v("Install an app on device.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("installApp")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/path/to/file.apk'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-8"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-8"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("path")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" path to apk file")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support only Android")]),t._v(" "),e("h3",{attrs:{id:"removeapp"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#removeapp"}},[t._v("#")]),t._v(" removeApp")]),t._v(" "),e("p",[t._v("Remove an app from the device.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("removeApp")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'appName'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'com.example.android.apis'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Appium: support only Android")]),t._v(" "),e("h4",{attrs:{id:"parameters-9"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-9"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("appId")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("bundleId")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v("?")]),t._v(" ID of bundle")])]),t._v(" "),e("h3",{attrs:{id:"resetapp"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#resetapp"}},[t._v("#")]),t._v(" resetApp")]),t._v(" "),e("p",[t._v("Reset the currently running app for current session.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("resetApp")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h3",{attrs:{id:"seecurrentactivityis"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#seecurrentactivityis"}},[t._v("#")]),t._v(" seeCurrentActivityIs")]),t._v(" "),e("p",[t._v("Check current activity on an Android device.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeCurrentActivityIs")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('".HomeScreenActivity"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-10"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-10"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("currentActivity")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support only Android")]),t._v(" "),e("h3",{attrs:{id:"seedeviceislocked"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#seedeviceislocked"}},[t._v("#")]),t._v(" seeDeviceIsLocked")]),t._v(" "),e("p",[t._v("Check whether the device is locked.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeDeviceIsLocked")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support only Android")]),t._v(" "),e("h3",{attrs:{id:"seedeviceisunlocked"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#seedeviceisunlocked"}},[t._v("#")]),t._v(" seeDeviceIsUnlocked")]),t._v(" "),e("p",[t._v("Check whether the device is not locked.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeDeviceIsUnlocked")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support only Android")]),t._v(" "),e("h3",{attrs:{id:"seeorientationis"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#seeorientationis"}},[t._v("#")]),t._v(" seeOrientationIs")]),t._v(" "),e("p",[t._v("Check the device orientation")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeOrientationIs")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'PORTRAIT'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeOrientationIs")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'LANDSCAPE'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-11"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-11"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("orientation")]),t._v(" "),e("strong",[t._v("("),e("code",[t._v('"LANDSCAPE"')]),t._v(" | "),e("code",[t._v('"PORTRAIT"')]),t._v(")")]),t._v(" LANDSCAPE or PORTRAITAppium: support Android and iOS")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")])]),t._v(" "),e("h3",{attrs:{id:"setorientation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#setorientation"}},[t._v("#")]),t._v(" setOrientation")]),t._v(" "),e("p",[t._v("Set a device orientation. Will fail, if app will not set orientation")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("setOrientation")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'PORTRAIT'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("setOrientation")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'LANDSCAPE'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-12"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-12"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("orientation")]),t._v(" "),e("strong",[t._v("("),e("code",[t._v('"LANDSCAPE"')]),t._v(" | "),e("code",[t._v('"PORTRAIT"')]),t._v(")")]),t._v(" LANDSCAPE or PORTRAITAppium: support Android and iOS")])]),t._v(" "),e("h3",{attrs:{id:"graballcontexts"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#graballcontexts"}},[t._v("#")]),t._v(" grabAllContexts")]),t._v(" "),e("p",[t._v("Get list of all available contexts")]),t._v(" "),e("div",{staticClass:"language- extra-class"},[e("pre",[e("code",[t._v("let contexts = await I.grabAllContexts();\n")])])]),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("<"),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array",target:"_blank",rel:"noopener noreferrer"}},[t._v("Array"),e("OutboundLink")],1),t._v("<"),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(">>")]),t._v(" Appium: support Android and iOS")]),t._v(" "),e("h3",{attrs:{id:"grabcontext"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#grabcontext"}},[t._v("#")]),t._v(" grabContext")]),t._v(" "),e("p",[t._v("Retrieve current context")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" context "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabContext")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("<("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | null)>")]),t._v(" Appium: support Android and iOS")]),t._v(" "),e("h3",{attrs:{id:"grabcurrentactivity"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#grabcurrentactivity"}},[t._v("#")]),t._v(" grabCurrentActivity")]),t._v(" "),e("p",[t._v("Get current device activity.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" activity "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabCurrentActivity")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("<"),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(">")]),t._v(" Appium: support only Android")]),t._v(" "),e("h3",{attrs:{id:"grabnetworkconnection"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#grabnetworkconnection"}},[t._v("#")]),t._v(" grabNetworkConnection")]),t._v(" "),e("p",[t._v("Get information about the current network connection (Data/WIFI/Airplane).\nThe actual server value will be a number. However WebdriverIO additional\nproperties to the response object to allow easier assertions.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" con "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabNetworkConnection")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("<{}>")]),t._v(" Appium: support only Android")]),t._v(" "),e("h3",{attrs:{id:"graborientation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#graborientation"}},[t._v("#")]),t._v(" grabOrientation")]),t._v(" "),e("p",[t._v("Get current orientation.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" orientation "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabOrientation")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("<"),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(">")]),t._v(" Appium: support Android and iOS")]),t._v(" "),e("h3",{attrs:{id:"grabsettings"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#grabsettings"}},[t._v("#")]),t._v(" grabSettings")]),t._v(" "),e("p",[t._v("Get all the currently specified settings.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" settings "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabSettings")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("<"),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(">")]),t._v(" Appium: support Android and iOS")]),t._v(" "),e("h3",{attrs:{id:"switchtocontext"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#switchtocontext"}},[t._v("#")]),t._v(" switchToContext")]),t._v(" "),e("p",[t._v("Switch to the specified context.")]),t._v(" "),e("h4",{attrs:{id:"parameters-13"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-13"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("any")]),t._v(" the context to switch to")])]),t._v(" "),e("h3",{attrs:{id:"switchtoweb"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#switchtoweb"}},[t._v("#")]),t._v(" switchToWeb")]),t._v(" "),e("p",[t._v("Switches to web context.\nIf no context is provided switches to the first detected web context")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// switch to first web context")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("switchToWeb")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// or set the context explicitly")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("switchToWeb")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'WEBVIEW_io.selendroid.testapp'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-14"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-14"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v("?")])])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")])]),t._v(" "),e("h3",{attrs:{id:"switchtonative"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#switchtonative"}},[t._v("#")]),t._v(" switchToNative")]),t._v(" "),e("p",[t._v("Switches to native context.\nBy default switches to NATIVE_APP context unless other specified.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("switchToNative")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// or set context explicitly")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("switchToNative")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'SOME_OTHER_CONTEXT'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-15"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-15"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("any?")]),t._v(" (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")])]),t._v(" "),e("h3",{attrs:{id:"startactivity"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#startactivity"}},[t._v("#")]),t._v(" startActivity")]),t._v(" "),e("p",[t._v("Start an arbitrary Android activity during a session.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("startActivity")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'io.selendroid.testapp'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.RegisterUserActivity'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Appium: support only Android")]),t._v(" "),e("h4",{attrs:{id:"parameters-16"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-16"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("appPackage")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("appActivity")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")])]),t._v(" "),e("h3",{attrs:{id:"setnetworkconnection"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#setnetworkconnection"}},[t._v("#")]),t._v(" setNetworkConnection")]),t._v(" "),e("p",[t._v("Set network connection mode.")]),t._v(" "),e("ul",[e("li",[t._v("airplane mode")]),t._v(" "),e("li",[t._v("wifi mode")]),t._v(" "),e("li",[t._v("data data")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("setNetworkConnection")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// airplane mode off, wifi off, data off")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("setNetworkConnection")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// airplane mode on, wifi off, data off")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("setNetworkConnection")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// airplane mode off, wifi on, data off")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("setNetworkConnection")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("4")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// airplane mode off, wifi off, data on")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("setNetworkConnection")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("6")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// airplane mode off, wifi on, data on")]),t._v("\n")])])]),e("p",[t._v("See corresponding "),e("a",{attrs:{href:"https://webdriver.io/docs/api/chromium/#setnetworkconnection",target:"_blank",rel:"noopener noreferrer"}},[t._v("webdriverio reference"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("p",[t._v("Appium: support only Android")]),t._v(" "),e("h4",{attrs:{id:"parameters-17"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-17"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("value")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" The network connection mode bitmask")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("<"),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1),t._v(">")])]),t._v(" "),e("h3",{attrs:{id:"setsettings"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#setsettings"}},[t._v("#")]),t._v(" setSettings")]),t._v(" "),e("p",[t._v("Update the current setting on the device")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("setSettings")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("cyberdelia")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'open'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-18"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-18"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("settings")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1)]),t._v(" objectAppium: support Android and iOS")])]),t._v(" "),e("h3",{attrs:{id:"hidedevicekeyboard"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#hidedevicekeyboard"}},[t._v("#")]),t._v(" hideDeviceKeyboard")]),t._v(" "),e("p",[t._v("Hide the keyboard.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// taps outside to hide keyboard per default")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("hideDeviceKeyboard")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("hideDeviceKeyboard")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'tapOutside'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// or by pressing key")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("hideDeviceKeyboard")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'pressKey'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Done'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Appium: support Android and iOS")]),t._v(" "),e("h4",{attrs:{id:"parameters-19"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-19"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("strategy")]),t._v(" "),e("strong",[t._v("("),e("code",[t._v('"tapOutside"')]),t._v(" | "),e("code",[t._v('"pressKey"')]),t._v(")?")]),t._v(" Desired strategy to close keyboard (‘tapOutside’ or ‘pressKey’)")]),t._v(" "),e("li",[e("code",[t._v("key")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v("?")]),t._v(" Optional key")])]),t._v(" "),e("h3",{attrs:{id:"senddevicekeyevent"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#senddevicekeyevent"}},[t._v("#")]),t._v(" sendDeviceKeyEvent")]),t._v(" "),e("p",[t._v("Send a key event to the device.\nList of keys: "),e("a",{attrs:{href:"https://developer.android.com/reference/android/view/KeyEvent.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://developer.android.com/reference/android/view/KeyEvent.html"),e("OutboundLink")],1)]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendDeviceKeyEvent")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-20"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-20"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("keyValue")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" Device specific key value")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support only Android")]),t._v(" "),e("h3",{attrs:{id:"opennotifications"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#opennotifications"}},[t._v("#")]),t._v(" openNotifications")]),t._v(" "),e("p",[t._v("Open the notifications panel on the device.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("openNotifications")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support only Android")]),t._v(" "),e("h3",{attrs:{id:"maketouchaction"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#maketouchaction"}},[t._v("#")]),t._v(" makeTouchAction")]),t._v(" "),e("p",[t._v("The Touch Action API provides the basis of all gestures that can be\nautomated in Appium. At its core is the ability to chain together ad hoc\nindividual actions, which will then be applied to an element in the\napplication on the device.\n"),e("a",{attrs:{href:"http://webdriver.io/api/mobile/touchAction.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("See complete documentation"),e("OutboundLink")],1)]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("makeTouchAction")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"~buttonStartWebviewCD"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'tap'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-21"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-21"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")])]),t._v(" "),e("li",[e("code",[t._v("action")])])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support Android and iOS")]),t._v(" "),e("h3",{attrs:{id:"tap"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#tap"}},[t._v("#")]),t._v(" tap")]),t._v(" "),e("p",[t._v("Taps on element.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("tap")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"~buttonStartWebviewCD"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Shortcut for "),e("code",[t._v("makeTouchAction")])]),t._v(" "),e("h4",{attrs:{id:"parameters-22"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-22"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("any")])])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")])]),t._v(" "),e("h3",{attrs:{id:"swipe"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#swipe"}},[t._v("#")]),t._v(" swipe")]),t._v(" "),e("p",[t._v("Perform a swipe on the screen or an element.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" locator "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"#io.selendroid.testapp:id/LinearLayout1"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("swipe")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("800")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1200")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[e("a",{attrs:{href:"http://webdriver.io/api/mobile/swipe.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("See complete reference"),e("OutboundLink")],1)]),t._v(" "),e("h4",{attrs:{id:"parameters-23"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-23"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")])]),t._v(" "),e("li",[e("code",[t._v("xoffset")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("yoffset")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("speed")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" (optional), 1000 by default (optional, default "),e("code",[t._v("1000")]),t._v(")")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support Android and iOS")]),t._v(" "),e("h3",{attrs:{id:"performswipe"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#performswipe"}},[t._v("#")]),t._v(" performSwipe")]),t._v(" "),e("p",[t._v("Perform a swipe on the screen.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("performSwipe")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("x")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("300")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("y")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("x")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("y")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-24"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-24"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("from")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("to")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1)]),t._v(" Appium: support Android and iOS")])]),t._v(" "),e("h3",{attrs:{id:"swipedown"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#swipedown"}},[t._v("#")]),t._v(" swipeDown")]),t._v(" "),e("p",[t._v("Perform a swipe down on an element.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" locator "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"#io.selendroid.testapp:id/LinearLayout1"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("swipeDown")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// simple swipe")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("swipeDown")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("500")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// set speed")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("swipeDown")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1200")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// set offset and speed")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-25"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-25"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")])]),t._v(" "),e("li",[e("code",[t._v("yoffset")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1),t._v("?")]),t._v(" (optional) (optional, default "),e("code",[t._v("1000")]),t._v(")")]),t._v(" "),e("li",[e("code",[t._v("speed")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" (optional), 1000 by default (optional, default "),e("code",[t._v("1000")]),t._v(")")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support Android and iOS")]),t._v(" "),e("h3",{attrs:{id:"swipeleft"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#swipeleft"}},[t._v("#")]),t._v(" swipeLeft")]),t._v(" "),e("p",[t._v("Perform a swipe left on an element.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" locator "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"#io.selendroid.testapp:id/LinearLayout1"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("swipeLeft")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// simple swipe")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("swipeLeft")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("500")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// set speed")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("swipeLeft")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1200")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// set offset and speed")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-26"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-26"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")])]),t._v(" "),e("li",[e("code",[t._v("xoffset")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1),t._v("?")]),t._v(" (optional) (optional, default "),e("code",[t._v("1000")]),t._v(")")]),t._v(" "),e("li",[e("code",[t._v("speed")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" (optional), 1000 by default (optional, default "),e("code",[t._v("1000")]),t._v(")")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support Android and iOS")]),t._v(" "),e("h3",{attrs:{id:"swiperight"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#swiperight"}},[t._v("#")]),t._v(" swipeRight")]),t._v(" "),e("p",[t._v("Perform a swipe right on an element.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" locator "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"#io.selendroid.testapp:id/LinearLayout1"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("swipeRight")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// simple swipe")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("swipeRight")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("500")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// set speed")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("swipeRight")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1200")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// set offset and speed")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-27"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-27"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")])]),t._v(" "),e("li",[e("code",[t._v("xoffset")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1),t._v("?")]),t._v(" (optional) (optional, default "),e("code",[t._v("1000")]),t._v(")")]),t._v(" "),e("li",[e("code",[t._v("speed")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" (optional), 1000 by default (optional, default "),e("code",[t._v("1000")]),t._v(")")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support Android and iOS")]),t._v(" "),e("h3",{attrs:{id:"swipeup"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#swipeup"}},[t._v("#")]),t._v(" swipeUp")]),t._v(" "),e("p",[t._v("Perform a swipe up on an element.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" locator "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"#io.selendroid.testapp:id/LinearLayout1"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("swipeUp")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// simple swipe")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("swipeUp")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("500")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// set speed")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("swipeUp")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("locator"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1200")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1000")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// set offset and speed")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-28"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-28"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")])]),t._v(" "),e("li",[e("code",[t._v("yoffset")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1),t._v("?")]),t._v(" (optional) (optional, default "),e("code",[t._v("1000")]),t._v(")")]),t._v(" "),e("li",[e("code",[t._v("speed")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" (optional), 1000 by default (optional, default "),e("code",[t._v("1000")]),t._v(")")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support Android and iOS")]),t._v(" "),e("h3",{attrs:{id:"swipeto"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#swipeto"}},[t._v("#")]),t._v(" swipeTo")]),t._v(" "),e("p",[t._v("Perform a swipe in selected direction on an element to searchable element.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("swipeTo")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"android.widget.CheckBox"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// searchable element")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"//android.widget.ScrollView/android.widget.LinearLayout"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// scroll element")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"up"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// direction")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("30")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("500")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-29"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-29"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("searchableLocator")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("scrollLocator")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("direction")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("timeout")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("offset")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("speed")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support Android and iOS")]),t._v(" "),e("h3",{attrs:{id:"touchperform"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#touchperform"}},[t._v("#")]),t._v(" touchPerform")]),t._v(" "),e("p",[t._v("Performs a specific touch action.\nThe action object need to contain the action name, x/y coordinates")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("touchPerform")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("action")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'press'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("options")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("x")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("100")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("y")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("action")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'release'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("touchPerform")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("action")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'tap'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("options")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("element")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'1'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// json web element was queried before")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("x")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// x offset")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("y")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("20")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// y offset")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("count")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// number of touches")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Appium: support Android and iOS")]),t._v(" "),e("h4",{attrs:{id:"parameters-30"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-30"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("actions")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array",target:"_blank",rel:"noopener noreferrer"}},[t._v("Array"),e("OutboundLink")],1)]),t._v(" Array of touch actions")])]),t._v(" "),e("h3",{attrs:{id:"pullfile"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#pullfile"}},[t._v("#")]),t._v(" pullFile")]),t._v(" "),e("p",[t._v("Pulls a file from the device.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("pullFile")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/storage/emulated/0/DCIM/logo.png'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'my/path'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// save file to output dir")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("pullFile")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/storage/emulated/0/DCIM/logo.png'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" output_dir"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-31"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-31"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("path")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("dest")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("<"),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(">")]),t._v(" Appium: support Android and iOS")]),t._v(" "),e("h3",{attrs:{id:"shakedevice"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#shakedevice"}},[t._v("#")]),t._v(" shakeDevice")]),t._v(" "),e("p",[t._v("Perform a shake action on the device.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("shakeDevice")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support only iOS")]),t._v(" "),e("h3",{attrs:{id:"rotate"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#rotate"}},[t._v("#")]),t._v(" rotate")]),t._v(" "),e("p",[t._v("Perform a rotation gesture centered on the specified element.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("rotate")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("120")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("120")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("p",[t._v("See corresponding "),e("a",{attrs:{href:"http://webdriver.io/api/mobile/rotate.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("webdriverio reference"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("h4",{attrs:{id:"parameters-32"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-32"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("x")])]),t._v(" "),e("li",[e("code",[t._v("y")])]),t._v(" "),e("li",[e("code",[t._v("duration")])]),t._v(" "),e("li",[e("code",[t._v("radius")])]),t._v(" "),e("li",[e("code",[t._v("rotation")])]),t._v(" "),e("li",[e("code",[t._v("touchCount")])])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support only iOS")]),t._v(" "),e("h3",{attrs:{id:"setimmediatevalue"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#setimmediatevalue"}},[t._v("#")]),t._v(" setImmediateValue")]),t._v(" "),e("p",[t._v("Set immediate value in app.")]),t._v(" "),e("p",[t._v("See corresponding "),e("a",{attrs:{href:"http://webdriver.io/api/mobile/setImmediateValue.html",target:"_blank",rel:"noopener noreferrer"}},[t._v("webdriverio reference"),e("OutboundLink")],1),t._v(".")]),t._v(" "),e("h4",{attrs:{id:"parameters-33"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-33"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("id")])]),t._v(" "),e("li",[e("code",[t._v("value")])])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support only iOS")]),t._v(" "),e("h3",{attrs:{id:"simulatetouchid"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#simulatetouchid"}},[t._v("#")]),t._v(" simulateTouchId")]),t._v(" "),e("p",[t._v("Simulate Touch ID with either valid (match == true) or invalid (match == false) fingerprint.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("touchId")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// simulates valid fingerprint")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("touchId")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// simulates valid fingerprint")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("touchId")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// simulates invalid fingerprint")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-34"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-34"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("match")])])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support only iOS\nTODO: not tested")]),t._v(" "),e("h3",{attrs:{id:"closeapp"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#closeapp"}},[t._v("#")]),t._v(" closeApp")]),t._v(" "),e("p",[t._v("Close the given application.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("closeApp")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")]),t._v(" Appium: support both Android and iOS")]),t._v(" "),e("h3",{attrs:{id:"appendfield"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#appendfield"}},[t._v("#")]),t._v(" appendField")]),t._v(" "),e("p",[t._v("Appends text to a input field or textarea.\nField is located by name, label, CSS or XPath")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("appendField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#myTextField'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'appended'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// typing secret")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("appendField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("secret")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'123456'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-35"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-35"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("field")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" located by label|name|CSS|XPath|strict locator")]),t._v(" "),e("li",[e("code",[t._v("value")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" text value to append.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")]),t._v(" "),e("h3",{attrs:{id:"checkoption"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#checkoption"}},[t._v("#")]),t._v(" checkOption")]),t._v(" "),e("p",[t._v("Selects a checkbox or radio button.\nElement is located by label or name or CSS or XPath.")]),t._v(" "),e("p",[t._v("The second parameter is a context (CSS or XPath locator) to narrow the search.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("checkOption")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#agree'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("checkOption")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I Agree to Terms and Conditions'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("checkOption")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'agree'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'//form'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-36"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-36"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("field")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" checkbox located by label | name | CSS | XPath | strict locator.")]),t._v(" "),e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v("? | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" (optional, "),e("code",[t._v("null")]),t._v(" by default) element located by CSS | XPath | strict locator. (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")]),t._v(" "),e("h3",{attrs:{id:"click"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#click"}},[t._v("#")]),t._v(" click")]),t._v(" "),e("p",[t._v('Perform a click on a link or a button, given by a locator.\nIf a fuzzy locator is given, the page will be searched for a button, link, or image matching the locator string.\nFor buttons, the "value" attribute, "name" attribute, and inner text are searched. For links, the link text is searched.\nFor images, the "alt" attribute and inner text of any parent links are searched.')]),t._v(" "),e("p",[t._v("The second parameter is a context (CSS or XPath locator) to narrow the search.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// simple link")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Logout'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// button of form")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Submit'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// CSS button")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#form input[type=submit]'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// XPath")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'//form/*[@type=submit]'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// link in context")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Logout'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#nav'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// using strict locator")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("css")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'nav a.login'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-37"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-37"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" clickable link or button located by text, or any element located by CSS|XPath|strict locator.")]),t._v(" "),e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v("? | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(" | null)")]),t._v(" (optional, "),e("code",[t._v("null")]),t._v(" by default) element to search in CSS|XPath|Strict locator. (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")]),t._v(" "),e("h3",{attrs:{id:"dontseecheckboxischecked"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#dontseecheckboxischecked"}},[t._v("#")]),t._v(" dontSeeCheckboxIsChecked")]),t._v(" "),e("p",[t._v("Verifies that the specified checkbox is not checked.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeCheckboxIsChecked")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#agree'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// located by ID")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeCheckboxIsChecked")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I agree to terms'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// located by label")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeCheckboxIsChecked")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'agree'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// located by name")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-38"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-38"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("field")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" located by label|name|CSS|XPath|strict locator.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")]),t._v(" "),e("h3",{attrs:{id:"dontseeelement"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#dontseeelement"}},[t._v("#")]),t._v(" dontSeeElement")]),t._v(" "),e("p",[t._v("Opposite to "),e("code",[t._v("seeElement")]),t._v(". Checks that element is not visible (or in DOM)")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeElement")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.modal'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// modal is not shown")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-39"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-39"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" located by CSS|XPath|Strict locator.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")]),t._v(" "),e("h3",{attrs:{id:"dontseeinfield"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#dontseeinfield"}},[t._v("#")]),t._v(" dontSeeInField")]),t._v(" "),e("p",[t._v("Checks that value of input field or textarea doesn't equal to given value\nOpposite to "),e("code",[t._v("seeInField")]),t._v(".")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeInField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'email'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user@user.com'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// field by name")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeInField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("css")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'form input.email'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user@user.com'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// field by CSS")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-40"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-40"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("field")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" located by label|name|CSS|XPath|strict locator.")]),t._v(" "),e("li",[e("code",[t._v("value")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" value to check.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")]),t._v(" "),e("h3",{attrs:{id:"dontsee"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#dontsee"}},[t._v("#")]),t._v(" dontSee")]),t._v(" "),e("p",[t._v("Opposite to "),e("code",[t._v("see")]),t._v(". Checks that a text is not present on a page.\nUse context parameter to narrow down the search.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSee")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// assume we are already logged in.")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSee")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.nav'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// no login inside .nav element")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-41"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-41"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("text")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" which is not present.")]),t._v(" "),e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")?")]),t._v(" (optional) element located by CSS|XPath|strict locator in which to perfrom search. (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")]),t._v(" "),e("h3",{attrs:{id:"fillfield"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#fillfield"}},[t._v("#")]),t._v(" fillField")]),t._v(" "),e("p",[t._v("Fills a text field or textarea, after clearing its value, with the given string.\nField is located by name, label, CSS, or XPath.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// by label")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Email'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'hello@world.com'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// by name")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("secret")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'123456'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// by CSS")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'form#login input[name=username]'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'John'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// or by strict locator")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("css")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'form#login input[name=username]'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'John'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-42"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-42"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("field")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" located by label|name|CSS|XPath|strict locator.")]),t._v(" "),e("li",[e("code",[t._v("value")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" text value to fill.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")]),t._v(" "),e("h3",{attrs:{id:"grabtextfromall"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#grabtextfromall"}},[t._v("#")]),t._v(" grabTextFromAll")]),t._v(" "),e("p",[t._v("Retrieves all texts from an element located by CSS or XPath and returns it to test.\nResumes test execution, so "),e("strong",[t._v("should be used inside async with "),e("code",[t._v("await")])]),t._v(" operator.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" pins "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabTextFromAll")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#pin li'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-43"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-43"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" element located by CSS|XPath|strict locator.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("<"),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array",target:"_blank",rel:"noopener noreferrer"}},[t._v("Array"),e("OutboundLink")],1),t._v("<"),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(">>")]),t._v(" attribute value")]),t._v(" "),e("h3",{attrs:{id:"grabtextfrom"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#grabtextfrom"}},[t._v("#")]),t._v(" grabTextFrom")]),t._v(" "),e("p",[t._v("Retrieves a text from an element located by CSS or XPath and returns it to test.\nResumes test execution, so "),e("strong",[t._v("should be used inside async with "),e("code",[t._v("await")])]),t._v(" operator.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" pin "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabTextFrom")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#pin'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("If multiple elements found returns first element.")]),t._v(" "),e("h4",{attrs:{id:"parameters-44"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-44"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" element located by CSS|XPath|strict locator.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("<"),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(">")]),t._v(" attribute value")]),t._v(" "),e("h3",{attrs:{id:"grabnumberofvisibleelements"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#grabnumberofvisibleelements"}},[t._v("#")]),t._v(" grabNumberOfVisibleElements")]),t._v(" "),e("p",[t._v("Grab number of visible elements by locator.\nResumes test execution, so "),e("strong",[t._v("should be used inside async function with "),e("code",[t._v("await")])]),t._v(" operator.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" numOfElements "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabNumberOfVisibleElements")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'p'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-45"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-45"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" located by CSS|XPath|strict locator.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("<"),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1),t._v(">")]),t._v(" number of visible elements")]),t._v(" "),e("h3",{attrs:{id:"grabattributefrom"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#grabattributefrom"}},[t._v("#")]),t._v(" grabAttributeFrom")]),t._v(" "),e("p",[t._v('Can be used for apps only with several values ("contentDescription", "text", "className", "resourceId")')]),t._v(" "),e("p",[t._v("Retrieves an attribute from an element located by CSS or XPath and returns it to test.\nResumes test execution, so "),e("strong",[t._v("should be used inside async with "),e("code",[t._v("await")])]),t._v(" operator.\nIf more than one element is found - attribute of first element is returned.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" hint "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabAttributeFrom")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#tooltip'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'title'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-46"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-46"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" element located by CSS|XPath|strict locator.")]),t._v(" "),e("li",[e("code",[t._v("attr")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" attribute name.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("<"),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(">")]),t._v(" attribute value")]),t._v(" "),e("h3",{attrs:{id:"grabattributefromall"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#grabattributefromall"}},[t._v("#")]),t._v(" grabAttributeFromAll")]),t._v(" "),e("p",[t._v('Can be used for apps only with several values ("contentDescription", "text", "className", "resourceId")\nRetrieves an array of attributes from elements located by CSS or XPath and returns it to test.\nResumes test execution, so '),e("strong",[t._v("should be used inside async with "),e("code",[t._v("await")])]),t._v(" operator.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" hints "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabAttributeFromAll")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.tooltip'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'title'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-47"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-47"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" element located by CSS|XPath|strict locator.")]),t._v(" "),e("li",[e("code",[t._v("attr")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" attribute name.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("<"),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array",target:"_blank",rel:"noopener noreferrer"}},[t._v("Array"),e("OutboundLink")],1),t._v("<"),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(">>")]),t._v(" attribute value")]),t._v(" "),e("h3",{attrs:{id:"grabvaluefromall"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#grabvaluefromall"}},[t._v("#")]),t._v(" grabValueFromAll")]),t._v(" "),e("p",[t._v("Retrieves an array of value from a form located by CSS or XPath and returns it to test.\nResumes test execution, so "),e("strong",[t._v("should be used inside async function with "),e("code",[t._v("await")])]),t._v(" operator.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" inputs "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabValueFromAll")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'//form/input'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-48"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-48"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" field located by label|name|CSS|XPath|strict locator.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("<"),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array",target:"_blank",rel:"noopener noreferrer"}},[t._v("Array"),e("OutboundLink")],1),t._v("<"),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(">>")]),t._v(" attribute value")]),t._v(" "),e("h3",{attrs:{id:"grabvaluefrom"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#grabvaluefrom"}},[t._v("#")]),t._v(" grabValueFrom")]),t._v(" "),e("p",[t._v("Retrieves a value from a form element located by CSS or XPath and returns it to test.\nResumes test execution, so "),e("strong",[t._v("should be used inside async function with "),e("code",[t._v("await")])]),t._v(" operator.\nIf more than one element is found - value of first element is returned.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" email "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabValueFrom")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'input[name=email]'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-49"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-49"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" field located by label|name|CSS|XPath|strict locator.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("<"),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(">")]),t._v(" attribute value")]),t._v(" "),e("h3",{attrs:{id:"savescreenshot"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#savescreenshot"}},[t._v("#")]),t._v(" saveScreenshot")]),t._v(" "),e("p",[t._v("Saves a screenshot to ouput folder (set in codecept.conf.ts or codecept.conf.js).\nFilename is relative to output folder.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("saveScreenshot")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'debug.png'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-50"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-50"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("fileName")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" file name to save.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Promise",target:"_blank",rel:"noopener noreferrer"}},[t._v("Promise"),e("OutboundLink")],1),t._v("")])]),t._v(" "),e("h3",{attrs:{id:"scrollintoview"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#scrollintoview"}},[t._v("#")]),t._v(" scrollIntoView")]),t._v(" "),e("p",[t._v("Scroll element into viewport.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("scrollIntoView")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#submit'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("scrollIntoView")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#submit'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("scrollIntoView")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#submit'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("behavior")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"smooth"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("block")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"center"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("inline")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"center"')]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-51"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-51"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" located by CSS|XPath|strict locator.")]),t._v(" "),e("li",[e("code",[t._v("scrollIntoViewOptions")]),t._v(" "),e("strong",[t._v("(ScrollIntoViewOptions | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Boolean",target:"_blank",rel:"noopener noreferrer"}},[t._v("boolean"),e("OutboundLink")],1),t._v(")")]),t._v(" either alignToTop=true|false or scrollIntoViewOptions. See "),e("a",{attrs:{href:"https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView",target:"_blank",rel:"noopener noreferrer"}},[t._v("https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollIntoView"),e("OutboundLink")],1),t._v(".")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorderSupported only for web testing")]),t._v(" "),e("h3",{attrs:{id:"seecheckboxischecked"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#seecheckboxischecked"}},[t._v("#")]),t._v(" seeCheckboxIsChecked")]),t._v(" "),e("p",[t._v("Verifies that the specified checkbox is checked.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeCheckboxIsChecked")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Agree'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeCheckboxIsChecked")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#agree'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// I suppose user agreed to terms")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeCheckboxIsChecked")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("css")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#signup_form input[type=checkbox]'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-52"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-52"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("field")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" located by label|name|CSS|XPath|strict locator.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")]),t._v(" "),e("h3",{attrs:{id:"seeelement"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#seeelement"}},[t._v("#")]),t._v(" seeElement")]),t._v(" "),e("p",[t._v("Checks that a given Element is visible\nElement is located by CSS or XPath.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#modal'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-53"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-53"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" located by CSS|XPath|strict locator.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")]),t._v(" "),e("h3",{attrs:{id:"seeinfield"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#seeinfield"}},[t._v("#")]),t._v(" seeInField")]),t._v(" "),e("p",[t._v('Checks that the given input field or textarea equals to given value.\nFor fuzzy locators, fields are matched by label text, the "name" attribute, CSS, and XPath.')]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeInField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Username'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeInField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("css")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'form textarea'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Type your comment here'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeInField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'form input[type=hidden]'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'hidden_value'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeInField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#searchform input'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Search'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-54"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-54"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("field")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" located by label|name|CSS|XPath|strict locator.")]),t._v(" "),e("li",[e("code",[t._v("value")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" value to check.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")]),t._v(" "),e("h3",{attrs:{id:"see"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#see"}},[t._v("#")]),t._v(" see")]),t._v(" "),e("p",[t._v("Checks that a page contains a visible text.\nUse context parameter to narrow down the search.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Welcome'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// text welcome on a page")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Welcome'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.content'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// text inside .content div")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Register'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("css")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'form.register'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// use strict locator")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-55"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-55"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("text")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" expected on page.")]),t._v(" "),e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v("? | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" (optional, "),e("code",[t._v("null")]),t._v(" by default) element located by CSS|Xpath|strict locator in which to search for text. (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")]),t._v(" "),e("h3",{attrs:{id:"selectoption"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#selectoption"}},[t._v("#")]),t._v(" selectOption")]),t._v(" "),e("p",[t._v("Selects an option in a drop-down select.\nField is searched by label | name | CSS | XPath.\nOption is selected by visible text or by value.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("selectOption")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Choose Plan'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Monthly'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// select by label")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("selectOption")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'subscription'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Monthly'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// match option by text")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("selectOption")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'subscription'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'0'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// or by value")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("selectOption")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'//form/select[@name=account]'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Premium'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("selectOption")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'form select[name=account]'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Premium'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("selectOption")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("css")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'form select[name=account]'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Premium'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("p",[t._v("Provide an array for the second argument to select multiple options.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("selectOption")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Which OS do you use?'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Android'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'iOS'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-56"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-56"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("select")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" field located by label|name|CSS|XPath|strict locator.")]),t._v(" "),e("li",[e("code",[t._v("option")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array",target:"_blank",rel:"noopener noreferrer"}},[t._v("Array"),e("OutboundLink")],1),t._v(")")]),t._v(" visible text or value of option.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorderSupported only for web testing")]),t._v(" "),e("h3",{attrs:{id:"waitforelement"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#waitforelement"}},[t._v("#")]),t._v(" waitForElement")]),t._v(" "),e("p",[t._v("Waits for element to be present on page (by default waits for 1sec).\nElement can be located by CSS or XPath.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForElement")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.btn.continue'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForElement")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.btn.continue'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// wait for 5 secs")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-57"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-57"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" element located by CSS|XPath|strict locator.")]),t._v(" "),e("li",[e("code",[t._v("sec")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1),t._v("?")]),t._v(" (optional, "),e("code",[t._v("1")]),t._v(" by default) time in seconds to wait (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")]),t._v(" "),e("h3",{attrs:{id:"waitforvisible"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#waitforvisible"}},[t._v("#")]),t._v(" waitForVisible")]),t._v(" "),e("p",[t._v("Waits for an element to become visible on a page (by default waits for 1sec).\nElement can be located by CSS or XPath.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForVisible")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#popup'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-58"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-58"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" element located by CSS|XPath|strict locator.")]),t._v(" "),e("li",[e("code",[t._v("sec")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" (optional, "),e("code",[t._v("1")]),t._v(" by default) time in seconds to wait (optional, default "),e("code",[t._v("1")]),t._v(")")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")]),t._v(" "),e("h3",{attrs:{id:"waitforinvisible"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#waitforinvisible"}},[t._v("#")]),t._v(" waitForInvisible")]),t._v(" "),e("p",[t._v("Waits for an element to be removed or become invisible on a page (by default waits for 1sec).\nElement can be located by CSS or XPath.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForInvisible")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#popup'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-59"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-59"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" element located by CSS|XPath|strict locator.")]),t._v(" "),e("li",[e("code",[t._v("sec")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" (optional, "),e("code",[t._v("1")]),t._v(" by default) time in seconds to wait (optional, default "),e("code",[t._v("1")]),t._v(")")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")]),t._v(" "),e("h3",{attrs:{id:"waitfortext"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#waitfortext"}},[t._v("#")]),t._v(" waitForText")]),t._v(" "),e("p",[t._v("Waits for a text to appear (by default waits for 1sec).\nElement can be located by CSS or XPath.\nNarrow down search results by providing context.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForText")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Thank you, form has been submitted'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForText")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Thank you, form has been submitted'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("5")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#modal'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-60"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-60"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("text")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" to wait for.")]),t._v(" "),e("li",[e("code",[t._v("sec")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" (optional, "),e("code",[t._v("1")]),t._v(" by default) time in seconds to wait (optional, default "),e("code",[t._v("1")]),t._v(")")]),t._v(" "),e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")?")]),t._v(" (optional) element located by CSS|XPath|strict locator. (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")])])}),[],!1,null,null,null);e.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/55.25850abe.js b/assets/js/55.25850abe.js new file mode 100644 index 00000000..c28cf918 --- /dev/null +++ b/assets/js/55.25850abe.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[55],{354:function(t,e,a){"use strict";a.r(e);var s=a(14),n=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h1",{attrs:{id:"detox"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#detox"}},[t._v("#")]),t._v(" Detox")]),t._v(" "),e("h2",{attrs:{id:"detox-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#detox-2"}},[t._v("#")]),t._v(" Detox")]),t._v(" "),e("p",[e("strong",[t._v("Extends Helper")])]),t._v(" "),e("p",[t._v("This is a wrapper on top of "),e("a",{attrs:{href:"https://github.com/wix/Detox",target:"_blank",rel:"noopener noreferrer"}},[t._v("Detox"),e("OutboundLink")],1),t._v(" library, aimied to unify testing experience for CodeceptJS framework.\nDetox provides a grey box testing for mobile applications, playing especially good for React Native apps.")]),t._v(" "),e("p",[t._v("Detox plays quite differently from Appium. To establish detox testing you need to build a mobile application in a special way to inject Detox code.\nThis why "),e("strong",[t._v("Detox is grey box testing")]),t._v(" solution, so you need access to application source code, and a way to build and execute it on emulator.")]),t._v(" "),e("p",[t._v("Comparing to Appium, Detox runs faster and more stable but requires an additional setup for build.")]),t._v(" "),e("h3",{attrs:{id:"setup"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#setup"}},[t._v("#")]),t._v(" Setup")]),t._v(" "),e("ol",[e("li",[e("p",[e("a",{attrs:{href:"https://wix.github.io/Detox/docs/introduction/project-setup",target:"_blank",rel:"noopener noreferrer"}},[t._v("Install and configure Detox"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("p",[e("a",{attrs:{href:"https://wix.github.io/Detox/docs/introduction/project-setup#step-5-build-the-app",target:"_blank",rel:"noopener noreferrer"}},[t._v("Build an application"),e("OutboundLink")],1),t._v(" using "),e("code",[t._v("detox build")]),t._v(" command.")])]),t._v(" "),e("li",[e("p",[t._v("Install "),e("a",{attrs:{href:"https://codecept.io",target:"_blank",rel:"noopener noreferrer"}},[t._v("CodeceptJS"),e("OutboundLink")],1),t._v(" and detox-helper:")]),t._v(" "),e("p",[t._v("npm i @codeceptjs/detox-helper --save")])])]),t._v(" "),e("p",[t._v("Detox configuration is required in "),e("code",[t._v("package.json")]),t._v(" under "),e("code",[t._v("detox")]),t._v(" section.")]),t._v(" "),e("p",[t._v("If you completed step 1 and step 2 you should have a configuration similar this:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[t._v(" "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"detox"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"configurations"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"ios.sim.debug"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"device"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"simulator"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"app"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ios.debug"')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"apps"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"ios.debug"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"type"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ios.app"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"binaryPath"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"../test/ios/build/Build/Products/Debug-iphonesimulator/MyTestApp.app"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"build"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"xcodebuild -workspace ../test/ios/MyTestApp.xcworkspace -scheme MyTestApp -configuration Debug -sdk iphonesimulator -derivedDataPath ../test/ios/build"')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"devices"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"simulator"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"type"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"ios.simulator"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"device"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"type"')]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"iPhone 15"')]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("h3",{attrs:{id:"configuration"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#configuration"}},[t._v("#")]),t._v(" Configuration")]),t._v(" "),e("p",[t._v("Besides Detox configuration, CodeceptJS should also be configured to use Detox.")]),t._v(" "),e("p",[t._v("In "),e("code",[t._v("codecept.conf.js")]),t._v(" enable Detox helper:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Detox")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("require")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@codeceptjs/detox-helper'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("configuration")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("p",[t._v("It's important to specify a package name under "),e("code",[t._v("require")]),t._v(" section and current detox configuration taken from "),e("code",[t._v("package.json")]),t._v(".")]),t._v(" "),e("p",[t._v("Options:")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("configuration")]),t._v(" - a detox configuration name. Required.")]),t._v(" "),e("li",[e("code",[t._v("reloadReactNative")]),t._v(" - should be enabled for React Native applications.")]),t._v(" "),e("li",[e("code",[t._v("reuse")]),t._v(" - reuse application for tests. By default, Detox reinstalls and relaunches app.")]),t._v(" "),e("li",[e("code",[t._v("registerGlobals")]),t._v(" - (default: true) Register Detox helper functions "),e("code",[t._v("by")]),t._v(", "),e("code",[t._v("element")]),t._v(", "),e("code",[t._v("expect")]),t._v(", "),e("code",[t._v("waitFor")]),t._v(" globally.")])]),t._v(" "),e("h3",{attrs:{id:"parameters"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("config")])])]),t._v(" "),e("h3",{attrs:{id:"appendfield"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#appendfield"}},[t._v("#")]),t._v(" appendField")]),t._v(" "),e("p",[t._v("Appends text into the field.\nA field can be located by text, accessibility id, id.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("appendField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'name'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-2"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("field")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")])]),t._v(" "),e("li",[e("code",[t._v("value")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])])]),t._v(" "),e("h3",{attrs:{id:"checkifelementexists"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#checkifelementexists"}},[t._v("#")]),t._v(" checkIfElementExists")]),t._v(" "),e("p",[t._v("Checks if an element exists.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("checkIfElementExists")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~edit'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// located by accessibility id")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("checkIfElementExists")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~edit'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#menu'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// element inside #menu")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-3"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" element to locate")]),t._v(" "),e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(" | null)")]),t._v(" context element (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"clearfield"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#clearfield"}},[t._v("#")]),t._v(" clearField")]),t._v(" "),e("p",[t._v("Clears a text field.\nA field can be located by text, accessibility id, id.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("clearField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~name'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-4"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("field")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" an input element to clear")])]),t._v(" "),e("h3",{attrs:{id:"click"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#click"}},[t._v("#")]),t._v(" click")]),t._v(" "),e("p",[t._v("Clicks on an element.\nElement can be located by its text or id or accessibility id")]),t._v(" "),e("p",[t._v("The second parameter is a context (id | type | accessibility id) to narrow the search.")]),t._v(" "),e("p",[t._v("Same as "),e("a",{attrs:{href:"#tap"}},[t._v("tap")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate by text")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~nav-1'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate by accessibility label")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#user'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate by id")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#nav'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate by text inside #nav")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ios")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Save'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("android")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'SAVE'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#main'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// different texts on iOS and Android")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-5"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")])]),t._v(" "),e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(" | null)")]),t._v(" (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"clickatpoint"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#clickatpoint"}},[t._v("#")]),t._v(" clickAtPoint")]),t._v(" "),e("p",[t._v("Performs click on element with horizontal and vertical offset.\nAn element is located by text, id, accessibility id.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("clickAtPoint")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Save'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("clickAtPoint")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~save'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate by accessibility id")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-6"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-6"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")])]),t._v(" "),e("li",[e("code",[t._v("x")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" horizontal offset (optional, default "),e("code",[t._v("0")]),t._v(")")]),t._v(" "),e("li",[e("code",[t._v("y")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" vertical offset (optional, default "),e("code",[t._v("0")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"dontsee"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#dontsee"}},[t._v("#")]),t._v(" dontSee")]),t._v(" "),e("p",[t._v("Checks text not to be visible.\nUse second parameter to narrow down the search.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSee")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Record created'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSee")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Record updated'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#message'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSee")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Record deleted'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~message'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-7"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-7"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("text")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" to check invisibility")]),t._v(" "),e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(" | null)")]),t._v(" element in which to search for text (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"dontseeelement"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#dontseeelement"}},[t._v("#")]),t._v(" dontSeeElement")]),t._v(" "),e("p",[t._v("Checks that element is not visible.\nUse second parameter to narrow down the search.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeElement")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~edit'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// located by accessibility id")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeElement")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~edit'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#menu'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// element inside #menu")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-8"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-8"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" element to locate")]),t._v(" "),e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(" | null)")]),t._v(" context element (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"dontseeelementexists"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#dontseeelementexists"}},[t._v("#")]),t._v(" dontSeeElementExists")]),t._v(" "),e("p",[t._v("Checks that element not exists.\nUse second parameter to narrow down the search.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeElementExist")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~edit'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// located by accessibility id")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeElementExist")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~edit'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#menu'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// element inside #menu")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-9"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-9"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" element to locate")]),t._v(" "),e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" context element (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"fillfield"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#fillfield"}},[t._v("#")]),t._v(" fillField")]),t._v(" "),e("p",[t._v("Fills in text field in an app.\nA field can be located by text, accessibility id, id.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Username'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~name'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fillField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("android")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'NAME'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ios")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'name'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-10"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-10"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("field")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" an input element to fill in")]),t._v(" "),e("li",[e("code",[t._v("value")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" value to fill")])]),t._v(" "),e("h3",{attrs:{id:"goback"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#goback"}},[t._v("#")]),t._v(" goBack")]),t._v(" "),e("p",[t._v("Goes back on Android")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("goBack")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// on Android only")]),t._v("\n")])])]),e("h3",{attrs:{id:"grabplatform"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#grabplatform"}},[t._v("#")]),t._v(" grabPlatform")]),t._v(" "),e("p",[t._v("Grab the device platform")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" platform "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabPlatform")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h3",{attrs:{id:"installapp"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#installapp"}},[t._v("#")]),t._v(" installApp")]),t._v(" "),e("p",[t._v("Installs a configured application.\nApplication is installed by default.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("installApp")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h3",{attrs:{id:"launchapp"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#launchapp"}},[t._v("#")]),t._v(" launchApp")]),t._v(" "),e("p",[t._v("Launches an application. If application instance already exists, use "),e("a",{attrs:{href:"#relaunchApp"}},[t._v("relaunchApp")]),t._v(".")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("launchApp")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h3",{attrs:{id:"longpress"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#longpress"}},[t._v("#")]),t._v(" longPress")]),t._v(" "),e("p",[t._v("Taps an element and holds for a requested time.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("longPress")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate by text, hold for 2 seconds")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("longPress")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~nav'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate by accessibility label, hold for second")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("longPress")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Update'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#menu'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate by text inside #menu, hold for 2 seconds")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-11"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-11"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" element to locate")]),t._v(" "),e("li",[e("code",[t._v("sec")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" number of seconds to hold tap")]),t._v(" "),e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(" | null)")]),t._v(" context element (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"multitap"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#multitap"}},[t._v("#")]),t._v(" multiTap")]),t._v(" "),e("p",[t._v("Multi taps on an element.\nElement can be located by its text or id or accessibility id.")]),t._v(" "),e("p",[t._v("Set the number of taps in second argument.\nOptionally define the context element by third argument.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("multiTap")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate by text")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("multiTap")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~nav'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate by accessibility label")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("multiTap")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#user'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate by id")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("multiTap")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Update'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#menu'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate by id")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-12"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-12"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" element to locate")]),t._v(" "),e("li",[e("code",[t._v("num")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" number of taps")]),t._v(" "),e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(" | null)")]),t._v(" context element (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"relaunchapp"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#relaunchapp"}},[t._v("#")]),t._v(" relaunchApp")]),t._v(" "),e("p",[t._v("Relaunches an application.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("relaunchApp")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h3",{attrs:{id:"runonandroid"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#runonandroid"}},[t._v("#")]),t._v(" runOnAndroid")]),t._v(" "),e("p",[t._v("Execute code only on Android")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("runOnAndroid")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Button'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hi, Android'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-13"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-13"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("fn")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function",target:"_blank",rel:"noopener noreferrer"}},[t._v("Function"),e("OutboundLink")],1)]),t._v(" a function which will be executed on android")])]),t._v(" "),e("h3",{attrs:{id:"runonios"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#runonios"}},[t._v("#")]),t._v(" runOnIOS")]),t._v(" "),e("p",[t._v("Execute code only on iOS")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("runOnIOS")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Button'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Hi, IOS'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-14"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-14"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("fn")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function",target:"_blank",rel:"noopener noreferrer"}},[t._v("Function"),e("OutboundLink")],1)]),t._v(" a function which will be executed on iOS")])]),t._v(" "),e("h3",{attrs:{id:"savescreenshot"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#savescreenshot"}},[t._v("#")]),t._v(" saveScreenshot")]),t._v(" "),e("p",[t._v("Saves a screenshot to the output dir")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("saveScreenshot")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'main-window.png'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-15"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-15"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("name")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])])]),t._v(" "),e("h3",{attrs:{id:"scrolldown"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#scrolldown"}},[t._v("#")]),t._v(" scrollDown")]),t._v(" "),e("p",[t._v("Scrolls to the bottom of an element.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("scrollDown")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#container'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-16"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-16"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")])])]),t._v(" "),e("h3",{attrs:{id:"scrollleft"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#scrollleft"}},[t._v("#")]),t._v(" scrollLeft")]),t._v(" "),e("p",[t._v("Scrolls to the left of an element.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("scrollLeft")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#container'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-17"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-17"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")])])]),t._v(" "),e("h3",{attrs:{id:"scrollright"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#scrollright"}},[t._v("#")]),t._v(" scrollRight")]),t._v(" "),e("p",[t._v("Scrolls to the right of an element.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("scrollRight")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#container'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-18"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-18"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")])])]),t._v(" "),e("h3",{attrs:{id:"scrolltoelement"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#scrolltoelement"}},[t._v("#")]),t._v(" scrollToElement")]),t._v(" "),e("p",[t._v("Scrolls within a scrollable container to an element.")]),t._v(" "),e("h4",{attrs:{id:"parameters-19"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-19"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("targetLocator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" Locator of the element to scroll to")]),t._v(" "),e("li",[e("code",[t._v("containerLocator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" Locator of the scrollable container")]),t._v(" "),e("li",[e("code",[t._v("direction")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" 'up' or 'down' (optional, default "),e("code",[t._v("'down'")]),t._v(")")]),t._v(" "),e("li",[e("code",[t._v("offset")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" Offset for scroll, can be adjusted based on need (optional, default "),e("code",[t._v("100")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"scrollup"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#scrollup"}},[t._v("#")]),t._v(" scrollUp")]),t._v(" "),e("p",[t._v("Scrolls to the top of an element.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("scrollUp")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#container'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-20"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-20"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")])])]),t._v(" "),e("h3",{attrs:{id:"see"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#see"}},[t._v("#")]),t._v(" see")]),t._v(" "),e("p",[t._v("Checks text to be visible.\nUse second parameter to narrow down the search.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Record created'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Record updated'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#message'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("see")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Record deleted'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~message'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-21"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-21"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("text")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" to check visibility")]),t._v(" "),e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(" | null)")]),t._v(" element inside which to search for text (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"seeelement"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#seeelement"}},[t._v("#")]),t._v(" seeElement")]),t._v(" "),e("p",[t._v("Checks for visibility of an element.\nUse second parameter to narrow down the search.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~edit'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// located by accessibility id")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElement")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~edit'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#menu'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// element inside #menu")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-22"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-22"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" element to locate")]),t._v(" "),e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(" | null)")]),t._v(" context element (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"seeelementexists"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#seeelementexists"}},[t._v("#")]),t._v(" seeElementExists")]),t._v(" "),e("p",[t._v("Checks for existence of an element. An element can be visible or not.\nUse second parameter to narrow down the search.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElementExists")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~edit'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// located by accessibility id")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeElementExists")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~edit'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#menu'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// element inside #menu")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-23"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-23"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" element to locate")]),t._v(" "),e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" context element (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"setlandscapeorientation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#setlandscapeorientation"}},[t._v("#")]),t._v(" setLandscapeOrientation")]),t._v(" "),e("p",[t._v("Switches device to landscape orientation")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("setLandscapeOrientation")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h3",{attrs:{id:"setportraitorientation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#setportraitorientation"}},[t._v("#")]),t._v(" setPortraitOrientation")]),t._v(" "),e("p",[t._v("Switches device to portrait orientation")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("setPortraitOrientation")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h3",{attrs:{id:"shakedevice"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#shakedevice"}},[t._v("#")]),t._v(" shakeDevice")]),t._v(" "),e("p",[t._v("Shakes the device.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("shakeDevice")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h3",{attrs:{id:"swipedown"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#swipedown"}},[t._v("#")]),t._v(" swipeDown")]),t._v(" "),e("p",[t._v("Performs a swipe up inside an element.\nCan be "),e("code",[t._v("slow")]),t._v(" or "),e("code",[t._v("fast")]),t._v(" swipe.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("swipeUp")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#container'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-24"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-24"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" an element on which to perform swipe")]),t._v(" "),e("li",[e("code",[t._v("speed")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" a speed to perform: "),e("code",[t._v("slow")]),t._v(" or "),e("code",[t._v("fast")]),t._v(". (optional, default "),e("code",[t._v("'slow'")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"swipeleft"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#swipeleft"}},[t._v("#")]),t._v(" swipeLeft")]),t._v(" "),e("p",[t._v("Performs a swipe up inside an element.\nCan be "),e("code",[t._v("slow")]),t._v(" or "),e("code",[t._v("fast")]),t._v(" swipe.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("swipeUp")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#container'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-25"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-25"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" an element on which to perform swipe")]),t._v(" "),e("li",[e("code",[t._v("speed")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" a speed to perform: "),e("code",[t._v("slow")]),t._v(" or "),e("code",[t._v("fast")]),t._v(". (optional, default "),e("code",[t._v("'slow'")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"swiperight"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#swiperight"}},[t._v("#")]),t._v(" swipeRight")]),t._v(" "),e("p",[t._v("Performs a swipe up inside an element.\nCan be "),e("code",[t._v("slow")]),t._v(" or "),e("code",[t._v("fast")]),t._v(" swipe.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("swipeUp")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#container'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-26"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-26"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" an element on which to perform swipe")]),t._v(" "),e("li",[e("code",[t._v("speed")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" a speed to perform: "),e("code",[t._v("slow")]),t._v(" or "),e("code",[t._v("fast")]),t._v(". (optional, default "),e("code",[t._v("'slow'")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"swipeup"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#swipeup"}},[t._v("#")]),t._v(" swipeUp")]),t._v(" "),e("p",[t._v("Performs a swipe up inside an element.\nCan be "),e("code",[t._v("slow")]),t._v(" or "),e("code",[t._v("fast")]),t._v(" swipe.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("swipeUp")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#container'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-27"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-27"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" an element on which to perform swipe")]),t._v(" "),e("li",[e("code",[t._v("speed")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" a speed to perform: "),e("code",[t._v("slow")]),t._v(" or "),e("code",[t._v("fast")]),t._v(". (optional, default "),e("code",[t._v("'slow'")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"tap"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#tap"}},[t._v("#")]),t._v(" tap")]),t._v(" "),e("p",[t._v("Taps on an element.\nElement can be located by its text or id or accessibility id.")]),t._v(" "),e("p",[t._v("The second parameter is a context element to narrow the search.")]),t._v(" "),e("p",[t._v("Same as "),e("a",{attrs:{href:"#click"}},[t._v("click")])]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("tap")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate by text")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("tap")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~nav-1'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate by accessibility label")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("tap")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#user'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate by id")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("tap")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#nav'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate by text inside #nav")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("tap")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ios")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Save'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("android")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'SAVE'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#main'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// different texts on iOS and Android")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-28"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-28"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")])]),t._v(" "),e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(" | null)")]),t._v(" (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"tapbylabel"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#tapbylabel"}},[t._v("#")]),t._v(" tapByLabel")]),t._v(" "),e("p",[t._v("Clicks on an element.\nElement can be located by its label")]),t._v(" "),e("p",[t._v("The second parameter is a context (id | type | accessibility id) to narrow the search.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("tapByLabel")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate by text")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("tapByLabel")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Login'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#nav'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// locate by text inside #nav")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-29"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-29"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")])]),t._v(" "),e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(" | null)")]),t._v(" (optional, default "),e("code",[t._v("null")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"tapreturnkey"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#tapreturnkey"}},[t._v("#")]),t._v(" tapReturnKey")]),t._v(" "),e("p",[t._v("Taps return key.\nA field can be located by text, accessibility id, id.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("tapReturnKey")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Username'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("tapReturnKey")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'~name'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("tapReturnKey")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("android")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'NAME'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("ios")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'name'")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-30"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-30"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("field")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" an input element to fill in")])]),t._v(" "),e("h3",{attrs:{id:"wait"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#wait"}},[t._v("#")]),t._v(" wait")]),t._v(" "),e("p",[t._v("Waits for number of seconds")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("wait")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// waits for 2 seconds")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-31"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-31"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("sec")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" number of seconds to wait")])]),t._v(" "),e("h3",{attrs:{id:"waitforelement"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#waitforelement"}},[t._v("#")]),t._v(" waitForElement")]),t._v(" "),e("p",[t._v("Waits for an element to exist on page.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForElement")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#message'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// wait for 1 second")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-32"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-32"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" an element to wait for")]),t._v(" "),e("li",[e("code",[t._v("sec")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" number of seconds to wait, 5 by default (optional, default "),e("code",[t._v("5")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"waitforelementvisible"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#waitforelementvisible"}},[t._v("#")]),t._v(" waitForElementVisible")]),t._v(" "),e("p",[t._v("Waits for an element to be visible on page.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForElementVisible")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#message'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// wait for 1 second")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-33"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-33"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" an element to wait for")]),t._v(" "),e("li",[e("code",[t._v("sec")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" number of seconds to wait (optional, default "),e("code",[t._v("5")]),t._v(")")])]),t._v(" "),e("h3",{attrs:{id:"waittohide"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#waittohide"}},[t._v("#")]),t._v(" waitToHide")]),t._v(" "),e("p",[t._v("Waits an elmenet to become not visible.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitToHide")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#message'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// wait for 2 seconds")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-34"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-34"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" an element to wait for")]),t._v(" "),e("li",[e("code",[t._v("sec")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" number of seconds to wait (optional, default "),e("code",[t._v("5")]),t._v(")")])])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/56.4bcfa8a5.js b/assets/js/56.4bcfa8a5.js new file mode 100644 index 00000000..755367ba --- /dev/null +++ b/assets/js/56.4bcfa8a5.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[56],{357:function(a,e,t){"use strict";t.r(e);var r=t(14),s=Object(r.a)({},(function(){var a=this,e=a._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[e("h2",{attrs:{id:"expecthelper"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expecthelper"}},[a._v("#")]),a._v(" ExpectHelper")]),a._v(" "),e("p",[a._v("This helper allows performing assertions based on Chai.")]),a._v(" "),e("h3",{attrs:{id:"examples"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#examples"}},[a._v("#")]),a._v(" Examples")]),a._v(" "),e("p",[a._v("Zero-configuration when paired with other helpers like REST, Playwright:")]),a._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// inside codecept.conf.js")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[a._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[a._v("Playwright")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("...")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[a._v("Expect")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),e("h2",{attrs:{id:"methods"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#methods"}},[a._v("#")]),a._v(" Methods")]),a._v(" "),e("h3",{attrs:{id:"expectabove"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectabove"}},[a._v("#")]),a._v(" expectAbove")]),a._v(" "),e("h4",{attrs:{id:"parameters"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("aboveThan")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectbelow"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectbelow"}},[a._v("#")]),a._v(" expectBelow")]),a._v(" "),e("h4",{attrs:{id:"parameters-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-2"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("belowThan")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectcontain"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectcontain"}},[a._v("#")]),a._v(" expectContain")]),a._v(" "),e("h4",{attrs:{id:"parameters-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-3"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValueToContain")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectdeepequal"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectdeepequal"}},[a._v("#")]),a._v(" expectDeepEqual")]),a._v(" "),e("h4",{attrs:{id:"parameters-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-4"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectdeepequalexcluding"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectdeepequalexcluding"}},[a._v("#")]),a._v(" expectDeepEqualExcluding")]),a._v(" "),e("p",[a._v("expects members of two JSON objects are deeply equal excluding some properties")]),a._v(" "),e("h4",{attrs:{id:"parameters-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-5"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("fieldsToExclude")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectdeepincludemembers"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectdeepincludemembers"}},[a._v("#")]),a._v(" expectDeepIncludeMembers")]),a._v(" "),e("p",[a._v("expects an array to be a superset of another array")]),a._v(" "),e("h4",{attrs:{id:"parameters-6"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-6"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("superset")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("set")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectdeepmembers"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectdeepmembers"}},[a._v("#")]),a._v(" expectDeepMembers")]),a._v(" "),e("p",[a._v("expects members of two arrays are deeply equal")]),a._v(" "),e("h4",{attrs:{id:"parameters-7"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-7"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectempty"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectempty"}},[a._v("#")]),a._v(" expectEmpty")]),a._v(" "),e("h4",{attrs:{id:"parameters-8"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-8"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectendswith"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectendswith"}},[a._v("#")]),a._v(" expectEndsWith")]),a._v(" "),e("h4",{attrs:{id:"parameters-9"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-9"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValueToEndWith")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectequal"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectequal"}},[a._v("#")]),a._v(" expectEqual")]),a._v(" "),e("h4",{attrs:{id:"parameters-10"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-10"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectequalignorecase"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectequalignorecase"}},[a._v("#")]),a._v(" expectEqualIgnoreCase")]),a._v(" "),e("h4",{attrs:{id:"parameters-11"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-11"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectfalse"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectfalse"}},[a._v("#")]),a._v(" expectFalse")]),a._v(" "),e("h4",{attrs:{id:"parameters-12"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-12"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expecthasaproperty"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expecthasaproperty"}},[a._v("#")]),a._v(" expectHasAProperty")]),a._v(" "),e("h4",{attrs:{id:"parameters-13"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-13"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("propertyName")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expecthasproperty"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expecthasproperty"}},[a._v("#")]),a._v(" expectHasProperty")]),a._v(" "),e("h4",{attrs:{id:"parameters-14"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-14"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("propertyName")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectjsonschema"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectjsonschema"}},[a._v("#")]),a._v(" expectJsonSchema")]),a._v(" "),e("h4",{attrs:{id:"parameters-15"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-15"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("jsonSchema")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectjsonschemausingajv"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectjsonschemausingajv"}},[a._v("#")]),a._v(" expectJsonSchemaUsingAJV")]),a._v(" "),e("h4",{attrs:{id:"parameters-16"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-16"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("jsonSchema")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])]),a._v(" "),e("li",[e("code",[a._v("ajvOptions")]),a._v(" "),e("strong",[a._v("any?")]),a._v(" Pass AJV options")])]),a._v(" "),e("h3",{attrs:{id:"expectlengthabovethan"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectlengthabovethan"}},[a._v("#")]),a._v(" expectLengthAboveThan")]),a._v(" "),e("h4",{attrs:{id:"parameters-17"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-17"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("lengthAboveThan")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectlengthbelowthan"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectlengthbelowthan"}},[a._v("#")]),a._v(" expectLengthBelowThan")]),a._v(" "),e("h4",{attrs:{id:"parameters-18"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-18"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("lengthBelowThan")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectlengthof"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectlengthof"}},[a._v("#")]),a._v(" expectLengthOf")]),a._v(" "),e("h4",{attrs:{id:"parameters-19"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-19"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("length")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectmatchespattern"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectmatchespattern"}},[a._v("#")]),a._v(" expectMatchesPattern")]),a._v(" "),e("p",[a._v("expects a JSON object matches a provided pattern")]),a._v(" "),e("h4",{attrs:{id:"parameters-20"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-20"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedPattern")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectmatchregex"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectmatchregex"}},[a._v("#")]),a._v(" expectMatchRegex")]),a._v(" "),e("h4",{attrs:{id:"parameters-21"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-21"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("regex")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectnotcontain"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectnotcontain"}},[a._v("#")]),a._v(" expectNotContain")]),a._v(" "),e("h4",{attrs:{id:"parameters-22"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-22"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValueToNotContain")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectnotdeepequal"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectnotdeepequal"}},[a._v("#")]),a._v(" expectNotDeepEqual")]),a._v(" "),e("h4",{attrs:{id:"parameters-23"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-23"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectnotendswith"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectnotendswith"}},[a._v("#")]),a._v(" expectNotEndsWith")]),a._v(" "),e("h4",{attrs:{id:"parameters-24"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-24"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValueToNotEndWith")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectnotequal"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectnotequal"}},[a._v("#")]),a._v(" expectNotEqual")]),a._v(" "),e("h4",{attrs:{id:"parameters-25"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-25"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectnotstartswith"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectnotstartswith"}},[a._v("#")]),a._v(" expectNotStartsWith")]),a._v(" "),e("h4",{attrs:{id:"parameters-26"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-26"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValueToNotStartWith")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectstartswith"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectstartswith"}},[a._v("#")]),a._v(" expectStartsWith")]),a._v(" "),e("h4",{attrs:{id:"parameters-27"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-27"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValueToStartWith")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expecttobea"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expecttobea"}},[a._v("#")]),a._v(" expectToBeA")]),a._v(" "),e("h4",{attrs:{id:"parameters-28"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-28"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("type")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expecttobean"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expecttobean"}},[a._v("#")]),a._v(" expectToBeAn")]),a._v(" "),e("h4",{attrs:{id:"parameters-29"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-29"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("type")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expecttrue"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expecttrue"}},[a._v("#")]),a._v(" expectTrue")]),a._v(" "),e("h4",{attrs:{id:"parameters-30"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-30"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])])])}),[],!1,null,null,null);e.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/57.cebab491.js b/assets/js/57.cebab491.js new file mode 100644 index 00000000..1ee4fdac --- /dev/null +++ b/assets/js/57.cebab491.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[57],{355:function(a,e,t){"use strict";t.r(e);var r=t(14),s=Object(r.a)({},(function(){var a=this,e=a._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":a.$parent.slotKey}},[e("h2",{attrs:{id:"expecthelper"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expecthelper"}},[a._v("#")]),a._v(" ExpectHelper")]),a._v(" "),e("p",[a._v("This helper allows performing assertions based on Chai.")]),a._v(" "),e("h3",{attrs:{id:"examples"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#examples"}},[a._v("#")]),a._v(" Examples")]),a._v(" "),e("p",[a._v("Zero-configuration when paired with other helpers like REST, Playwright:")]),a._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[a._v("// inside codecept.conf.js")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[a._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[a._v("Playwright")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v("...")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[a._v("ExpectHelper")]),e("span",{pre:!0,attrs:{class:"token operator"}},[a._v(":")]),a._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v(",")]),a._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[a._v("}")]),a._v("\n")])])]),e("h2",{attrs:{id:"methods"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#methods"}},[a._v("#")]),a._v(" Methods")]),a._v(" "),e("h3",{attrs:{id:"expectabove"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectabove"}},[a._v("#")]),a._v(" expectAbove")]),a._v(" "),e("h4",{attrs:{id:"parameters"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("aboveThan")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectbelow"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectbelow"}},[a._v("#")]),a._v(" expectBelow")]),a._v(" "),e("h4",{attrs:{id:"parameters-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-2"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("belowThan")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectcontain"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectcontain"}},[a._v("#")]),a._v(" expectContain")]),a._v(" "),e("h4",{attrs:{id:"parameters-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-3"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValueToContain")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectdeepequal"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectdeepequal"}},[a._v("#")]),a._v(" expectDeepEqual")]),a._v(" "),e("h4",{attrs:{id:"parameters-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-4"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectdeepequalexcluding"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectdeepequalexcluding"}},[a._v("#")]),a._v(" expectDeepEqualExcluding")]),a._v(" "),e("p",[a._v("expects members of two JSON objects are deeply equal excluding some properties")]),a._v(" "),e("h4",{attrs:{id:"parameters-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-5"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("fieldsToExclude")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectdeepincludemembers"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectdeepincludemembers"}},[a._v("#")]),a._v(" expectDeepIncludeMembers")]),a._v(" "),e("p",[a._v("expects an array to be a superset of another array")]),a._v(" "),e("h4",{attrs:{id:"parameters-6"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-6"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("superset")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("set")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectdeepmembers"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectdeepmembers"}},[a._v("#")]),a._v(" expectDeepMembers")]),a._v(" "),e("p",[a._v("expects members of two arrays are deeply equal")]),a._v(" "),e("h4",{attrs:{id:"parameters-7"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-7"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectempty"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectempty"}},[a._v("#")]),a._v(" expectEmpty")]),a._v(" "),e("h4",{attrs:{id:"parameters-8"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-8"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectendswith"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectendswith"}},[a._v("#")]),a._v(" expectEndsWith")]),a._v(" "),e("h4",{attrs:{id:"parameters-9"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-9"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValueToEndWith")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectequal"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectequal"}},[a._v("#")]),a._v(" expectEqual")]),a._v(" "),e("h4",{attrs:{id:"parameters-10"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-10"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectequalignorecase"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectequalignorecase"}},[a._v("#")]),a._v(" expectEqualIgnoreCase")]),a._v(" "),e("h4",{attrs:{id:"parameters-11"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-11"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectfalse"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectfalse"}},[a._v("#")]),a._v(" expectFalse")]),a._v(" "),e("h4",{attrs:{id:"parameters-12"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-12"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expecthasaproperty"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expecthasaproperty"}},[a._v("#")]),a._v(" expectHasAProperty")]),a._v(" "),e("h4",{attrs:{id:"parameters-13"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-13"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("propertyName")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expecthasproperty"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expecthasproperty"}},[a._v("#")]),a._v(" expectHasProperty")]),a._v(" "),e("h4",{attrs:{id:"parameters-14"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-14"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("propertyName")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectjsonschema"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectjsonschema"}},[a._v("#")]),a._v(" expectJsonSchema")]),a._v(" "),e("h4",{attrs:{id:"parameters-15"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-15"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("jsonSchema")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectjsonschemausingajv"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectjsonschemausingajv"}},[a._v("#")]),a._v(" expectJsonSchemaUsingAJV")]),a._v(" "),e("h4",{attrs:{id:"parameters-16"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-16"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("jsonSchema")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])]),a._v(" "),e("li",[e("code",[a._v("ajvOptions")]),a._v(" "),e("strong",[a._v("any?")]),a._v(" Pass AJV options")])]),a._v(" "),e("h3",{attrs:{id:"expectlengthabovethan"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectlengthabovethan"}},[a._v("#")]),a._v(" expectLengthAboveThan")]),a._v(" "),e("h4",{attrs:{id:"parameters-17"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-17"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("lengthAboveThan")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectlengthbelowthan"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectlengthbelowthan"}},[a._v("#")]),a._v(" expectLengthBelowThan")]),a._v(" "),e("h4",{attrs:{id:"parameters-18"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-18"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("lengthBelowThan")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectlengthof"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectlengthof"}},[a._v("#")]),a._v(" expectLengthOf")]),a._v(" "),e("h4",{attrs:{id:"parameters-19"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-19"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("length")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectmatchespattern"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectmatchespattern"}},[a._v("#")]),a._v(" expectMatchesPattern")]),a._v(" "),e("p",[a._v("expects a JSON object matches a provided pattern")]),a._v(" "),e("h4",{attrs:{id:"parameters-20"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-20"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedPattern")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectmatchregex"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectmatchregex"}},[a._v("#")]),a._v(" expectMatchRegex")]),a._v(" "),e("h4",{attrs:{id:"parameters-21"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-21"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("regex")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectnotcontain"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectnotcontain"}},[a._v("#")]),a._v(" expectNotContain")]),a._v(" "),e("h4",{attrs:{id:"parameters-22"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-22"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValueToNotContain")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectnotdeepequal"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectnotdeepequal"}},[a._v("#")]),a._v(" expectNotDeepEqual")]),a._v(" "),e("h4",{attrs:{id:"parameters-23"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-23"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectnotendswith"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectnotendswith"}},[a._v("#")]),a._v(" expectNotEndsWith")]),a._v(" "),e("h4",{attrs:{id:"parameters-24"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-24"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValueToNotEndWith")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectnotequal"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectnotequal"}},[a._v("#")]),a._v(" expectNotEqual")]),a._v(" "),e("h4",{attrs:{id:"parameters-25"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-25"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectnotstartswith"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectnotstartswith"}},[a._v("#")]),a._v(" expectNotStartsWith")]),a._v(" "),e("h4",{attrs:{id:"parameters-26"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-26"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValueToNotStartWith")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expectstartswith"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expectstartswith"}},[a._v("#")]),a._v(" expectStartsWith")]),a._v(" "),e("h4",{attrs:{id:"parameters-27"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-27"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("actualValue")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("expectedValueToStartWith")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expecttobea"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expecttobea"}},[a._v("#")]),a._v(" expectToBeA")]),a._v(" "),e("h4",{attrs:{id:"parameters-28"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-28"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("type")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expecttobean"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expecttobean"}},[a._v("#")]),a._v(" expectToBeAn")]),a._v(" "),e("h4",{attrs:{id:"parameters-29"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-29"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("type")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])]),a._v(" "),e("h3",{attrs:{id:"expecttrue"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#expecttrue"}},[a._v("#")]),a._v(" expectTrue")]),a._v(" "),e("h4",{attrs:{id:"parameters-30"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-30"}},[a._v("#")]),a._v(" Parameters")]),a._v(" "),e("ul",[e("li",[e("code",[a._v("targetData")]),a._v(" "),e("strong",[a._v("any")])]),a._v(" "),e("li",[e("code",[a._v("customErrorMsg")]),a._v(" "),e("strong",[a._v("any?")])])])])}),[],!1,null,null,null);e.default=s.exports}}]); \ No newline at end of file diff --git a/assets/js/58.e3af4824.js b/assets/js/58.e3af4824.js new file mode 100644 index 00000000..29be36fc --- /dev/null +++ b/assets/js/58.e3af4824.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[58],{359:function(t,e,a){"use strict";a.r(e);var s=a(14),n=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"filesystem"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#filesystem"}},[t._v("#")]),t._v(" FileSystem")]),t._v(" "),e("p",[e("strong",[t._v("Extends Helper")])]),t._v(" "),e("p",[t._v("Helper for testing filesystem.\nCan be easily used to check file structures:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amInPath")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'test'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeFile")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'codecept.js'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeInThisFile")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'FileSystem'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("dontSeeInThisFile")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v('"WebDriver"')]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h2",{attrs:{id:"configuration"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#configuration"}},[t._v("#")]),t._v(" Configuration")]),t._v(" "),e("p",[t._v("Enable helper in config file:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("FileSystem")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("h2",{attrs:{id:"methods"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#methods"}},[t._v("#")]),t._v(" Methods")]),t._v(" "),e("h3",{attrs:{id:"aminpath"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#aminpath"}},[t._v("#")]),t._v(" amInPath")]),t._v(" "),e("p",[t._v("Enters a directory In local filesystem.\nStarts from a current directory")]),t._v(" "),e("h4",{attrs:{id:"parameters"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("openPath")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])])]),t._v(" "),e("h3",{attrs:{id:"dontseefilecontentsequal"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#dontseefilecontentsequal"}},[t._v("#")]),t._v(" dontSeeFileContentsEqual")]),t._v(" "),e("p",[t._v("Checks that contents of file found by "),e("code",[t._v("seeFile")]),t._v(" doesn't equal to text.")]),t._v(" "),e("h4",{attrs:{id:"parameters-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-2"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("text")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("encoding")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])])]),t._v(" "),e("h3",{attrs:{id:"dontseeinthisfile"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#dontseeinthisfile"}},[t._v("#")]),t._v(" dontSeeInThisFile")]),t._v(" "),e("p",[t._v("Checks that file found by "),e("code",[t._v("seeFile")]),t._v(" doesn't include text.")]),t._v(" "),e("h4",{attrs:{id:"parameters-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-3"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("text")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("encoding")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])])]),t._v(" "),e("h3",{attrs:{id:"grabfilenames"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#grabfilenames"}},[t._v("#")]),t._v(" grabFileNames")]),t._v(" "),e("p",[t._v("Returns file names in current directory.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("handleDownloads")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Download Files'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amInPath")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'output/downloads'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" downloadedFileNames "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabFileNames")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h3",{attrs:{id:"seefile"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#seefile"}},[t._v("#")]),t._v(" seeFile")]),t._v(" "),e("p",[t._v("Checks that file exists")]),t._v(" "),e("h4",{attrs:{id:"parameters-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-4"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("name")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])])]),t._v(" "),e("h3",{attrs:{id:"seefilecontentsequal"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#seefilecontentsequal"}},[t._v("#")]),t._v(" seeFileContentsEqual")]),t._v(" "),e("p",[t._v("Checks that contents of file found by "),e("code",[t._v("seeFile")]),t._v(" equal to text.")]),t._v(" "),e("h4",{attrs:{id:"parameters-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-5"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("text")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("encoding")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])])]),t._v(" "),e("h3",{attrs:{id:"seefilecontentsequalreferencefile"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#seefilecontentsequalreferencefile"}},[t._v("#")]),t._v(" seeFileContentsEqualReferenceFile")]),t._v(" "),e("p",[t._v("Checks that contents of the file found by "),e("code",[t._v("seeFile")]),t._v(" equal to contents of the file at "),e("code",[t._v("pathToReferenceFile")]),t._v(".")]),t._v(" "),e("h4",{attrs:{id:"parameters-6"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-6"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("pathToReferenceFile")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("encoding")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("encodingReference")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])])]),t._v(" "),e("h3",{attrs:{id:"seefilenamematching"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#seefilenamematching"}},[t._v("#")]),t._v(" seeFileNameMatching")]),t._v(" "),e("p",[t._v("Checks that file with a name including given text exists in the current directory.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("handleDownloads")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Download as PDF'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amInPath")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'output/downloads'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("seeFileNameMatching")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'.pdf'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-7"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-7"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("text")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])])]),t._v(" "),e("h3",{attrs:{id:"seeinthisfile"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#seeinthisfile"}},[t._v("#")]),t._v(" seeInThisFile")]),t._v(" "),e("p",[t._v("Checks that file found by "),e("code",[t._v("seeFile")]),t._v(" includes a text.")]),t._v(" "),e("h4",{attrs:{id:"parameters-8"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-8"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("text")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("encoding")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])])]),t._v(" "),e("h3",{attrs:{id:"waitforfile"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#waitforfile"}},[t._v("#")]),t._v(" waitForFile")]),t._v(" "),e("p",[t._v("Waits for the file to be present in the current directory.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("handleDownloads")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'downloads/largeFilesName.txt'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Download large File'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amInPath")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'output/downloads'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("waitForFile")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'largeFilesName.txt'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("10")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// wait 10 seconds for file")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-9"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-9"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("name")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("sec")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),e("OutboundLink")],1)]),t._v(" seconds to wait")])]),t._v(" "),e("h3",{attrs:{id:"writetofile"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#writetofile"}},[t._v("#")]),t._v(" writeToFile")]),t._v(" "),e("p",[t._v("Writes text to file")]),t._v(" "),e("h4",{attrs:{id:"parameters-10"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-10"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("name")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("text")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)])])])])}),[],!1,null,null,null);e.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/59.af1bb9b9.js b/assets/js/59.af1bb9b9.js new file mode 100644 index 00000000..5c537c9a --- /dev/null +++ b/assets/js/59.af1bb9b9.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[59],{360:function(t,e,a){"use strict";a.r(e);var s=a(14),r=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"graphql"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#graphql"}},[t._v("#")]),t._v(" GraphQL")]),t._v(" "),e("p",[e("strong",[t._v("Extends Helper")])]),t._v(" "),e("p",[t._v("GraphQL helper allows to send additional requests to a GraphQl endpoint during acceptance tests.\n"),e("a",{attrs:{href:"https://github.com/axios/axios",target:"_blank",rel:"noopener noreferrer"}},[t._v("Axios"),e("OutboundLink")],1),t._v(" library is used to perform requests.")]),t._v(" "),e("h2",{attrs:{id:"configuration"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#configuration"}},[t._v("#")]),t._v(" Configuration")]),t._v(" "),e("ul",[e("li",[t._v("endpoint: GraphQL base URL")]),t._v(" "),e("li",[t._v("timeout: timeout for requests in milliseconds. 10000ms by default")]),t._v(" "),e("li",[t._v("defaultHeaders: a list of default headers")]),t._v(" "),e("li",[t._v("onRequest: a async function which can update request object.")])]),t._v(" "),e("h2",{attrs:{id:"example"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#example"}},[t._v("#")]),t._v(" Example")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("GraphQL")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("endpoint")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'http://site.com/graphql/'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("onRequest")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("request")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n request"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headers"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("auth "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'123'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),e("h2",{attrs:{id:"access-from-helpers"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#access-from-helpers"}},[t._v("#")]),t._v(" Access From Helpers")]),t._v(" "),e("p",[t._v("Send GraphQL requests by accessing "),e("code",[t._v("_executeQuery")]),t._v(" method:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helpers"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'GraphQL'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("_executeQuery")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n url"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n data"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h2",{attrs:{id:"methods"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#methods"}},[t._v("#")]),t._v(" Methods")]),t._v(" "),e("h3",{attrs:{id:"parameters"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("config")])])]),t._v(" "),e("h3",{attrs:{id:"executequery"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#executequery"}},[t._v("#")]),t._v(" _executeQuery")]),t._v(" "),e("p",[t._v("Executes query via axios call")]),t._v(" "),e("h4",{attrs:{id:"parameters-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-2"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("request")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1)])])]),t._v(" "),e("h3",{attrs:{id:"preparegraphqlrequest"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#preparegraphqlrequest"}},[t._v("#")]),t._v(" _prepareGraphQLRequest")]),t._v(" "),e("p",[t._v("Prepares request for axios call")]),t._v(" "),e("h4",{attrs:{id:"parameters-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-3"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("operation")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("headers")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1)])])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1)]),t._v(" graphQLRequest")]),t._v(" "),e("h3",{attrs:{id:"ambearerauthenticated"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#ambearerauthenticated"}},[t._v("#")]),t._v(" amBearerAuthenticated")]),t._v(" "),e("p",[t._v("Adds a header for Bearer authentication")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// we use secret function to hide token from logs")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amBearerAuthenticated")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("secret")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'heregoestoken'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-4"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("accessToken")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | CodeceptJS.Secret)")]),t._v(" Bearer access token")])]),t._v(" "),e("h3",{attrs:{id:"haverequestheaders"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#haverequestheaders"}},[t._v("#")]),t._v(" haveRequestHeaders")]),t._v(" "),e("p",[t._v("Sets request headers for all requests of this test")]),t._v(" "),e("h4",{attrs:{id:"parameters-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-5"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("headers")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1)]),t._v(" headers list")])]),t._v(" "),e("h3",{attrs:{id:"sendmutation"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#sendmutation"}},[t._v("#")]),t._v(" sendMutation")]),t._v(" "),e("p",[t._v("Send query to GraphQL endpoint over http")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendMutation")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token template-string"}},[e("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("\n mutation createUser($user: UserInput!) {\n createUser(user: $user) {\n id\n name\n email\n }\n }\n ")]),e("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("user")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'John Doe'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("email")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john@xmail.com'")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-6"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-6"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("mutation")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("String"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("variables")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v("?")]),t._v(" that may go along with the mutation")]),t._v(" "),e("li",[e("code",[t._v("options")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v("?")]),t._v(" are additional query options")]),t._v(" "),e("li",[e("code",[t._v("headers")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v("?")])])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("any")]),t._v(" Promise"),e("any")],1),t._v(" "),e("h3",{attrs:{id:"sendquery"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#sendquery"}},[t._v("#")]),t._v(" sendQuery")]),t._v(" "),e("p",[t._v("Send query to GraphQL endpoint over http.\nReturns a response as a promise.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendQuery")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'{ users { name email }}'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// with variables")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" response "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendQuery")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'query getUser($id: ID) { user(id: $id) { name email }}'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("id")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" user "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" response"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("data"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-7"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-7"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("query")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("String"),e("OutboundLink")],1)])]),t._v(" "),e("li",[e("code",[t._v("variables")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v("?")]),t._v(" that may go along with the query")]),t._v(" "),e("li",[e("code",[t._v("options")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v("?")]),t._v(" are additional query options")]),t._v(" "),e("li",[e("code",[t._v("headers")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v("?")])])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("any")]),t._v(" Promise"),e("any")],1)])}),[],!1,null,null,null);e.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/6.7d4294fe.js b/assets/js/6.7d4294fe.js new file mode 100644 index 00000000..dd8f7910 --- /dev/null +++ b/assets/js/6.7d4294fe.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[6,18,24],{239:function(t,e,n){"use strict";n.d(e,"d",(function(){return r})),n.d(e,"a",(function(){return s})),n.d(e,"i",(function(){return a})),n.d(e,"f",(function(){return l})),n.d(e,"g",(function(){return u})),n.d(e,"h",(function(){return c})),n.d(e,"b",(function(){return p})),n.d(e,"e",(function(){return d})),n.d(e,"k",(function(){return h})),n.d(e,"l",(function(){return f})),n.d(e,"c",(function(){return b})),n.d(e,"j",(function(){return g}));n(89);const r=/#.*$/,i=/\.(md|html)$/,s=/\/$/,a=/^[a-z]+:/i;function o(t){return decodeURI(t).replace(r,"").replace(i,"")}function l(t){return a.test(t)}function u(t){return/^mailto:/.test(t)}function c(t){return/^tel:/.test(t)}function p(t){if(l(t))return t;const e=t.match(r),n=e?e[0]:"",i=o(t);return s.test(i)?t:i+".html"+n}function d(t,e){const n=t.hash,i=function(t){const e=t.match(r);if(e)return e[0]}(e);if(i&&n!==i)return!1;return o(t.path)===o(e)}function h(t,e,n){if(l(e))return{type:"external",path:e};n&&(e=function(t,e,n){const r=t.charAt(0);if("/"===r)return t;if("?"===r||"#"===r)return e+t;const i=e.split("/");n&&i[i.length-1]||i.pop();const s=t.replace(/^\//,"").split("/");for(let t=0;t({type:"auto",title:e.title,basePath:t.path,path:t.path+"#"+e.slug,children:e.children||[]}))}]}(t);const o=a.sidebar||s.sidebar;if(o){const{base:t,config:n}=function(t,e){if(Array.isArray(e))return{base:"/",config:e};for(const r in e)if(0===(n=t,/(\.html|\/)$/.test(n)?n:n+"/").indexOf(encodeURI(r)))return{base:r,config:e[r]};var n;return{}}(e,o);return n?n.map(e=>function t(e,n,r,i=1){if("string"==typeof e)return h(n,e,r);if(Array.isArray(e))return Object.assign(h(n,e[0],r),{title:e[1]});{i>3&&console.error("[vuepress] detected a too deep nested sidebar group.");const s=e.children||[];return 0===s.length&&e.path?Object.assign(h(n,e.path,r),{title:e.title}):{type:"group",path:e.path,title:e.title,sidebarDepth:e.sidebarDepth,children:s.map(e=>t(e,n,r,i+1)),collapsable:!1!==e.collapsable}}}(e,i,t)):[]}return[]}function b(t){let e;return(t=t.map(t=>Object.assign({},t))).forEach(t=>{2===t.level?e=t:e&&(e.children||(e.children=[])).push(t)}),t.filter(t=>2===t.level)}function g(t){return Object.assign(t,{type:t.items&&t.items.length?"links":"link"})}},241:function(t,e,n){},242:function(t,e,n){},243:function(t,e,n){},248:function(t,e,n){},249:function(t,e,n){"use strict";n.r(e);var r={name:"DropdownTransition",methods:{setHeight(t){t.style.height=t.scrollHeight+"px"},unsetHeight(t){t.style.height=""}}},i=(n(253),n(14)),s=Object(i.a)(r,(function(){return(0,this._self._c)("transition",{attrs:{name:"dropdown"},on:{enter:this.setHeight,"after-enter":this.unsetHeight,"before-leave":this.setHeight}},[this._t("default")],2)}),[],!1,null,null,null);e.default=s.exports},251:function(t,e,n){"use strict";n.r(e);var r=n(267),i=n(261),s=n(239);function a(t,e){return"group"===e.type&&e.children.some(e=>"group"===e.type?a(t,e):"page"===e.type&&Object(s.e)(t,e.path))}var o={name:"SidebarLinks",components:{SidebarGroup:r.default,SidebarLink:i.default},props:["items","depth","sidebarDepth"],data:()=>({openGroupIndex:0}),created(){this.refreshIndex()},watch:{$route(){this.refreshIndex()}},methods:{refreshIndex(){const t=function(t,e){for(let n=0;n-1&&(this.openGroupIndex=t)},toggleGroup(t){this.openGroupIndex=t===this.openGroupIndex?-1:t},isActive(t){return Object(s.e)(this.$route,t.regularPath)}}},l=n(14),u=Object(l.a)(o,(function(){var t=this,e=t._self._c;return t.items.length?e("ul",{staticClass:"sidebar-links"},t._l(t.items,(function(n,r){return e("li",{key:r},["group"===n.type?e("SidebarGroup",{attrs:{item:n,open:r===t.openGroupIndex,collapsable:n.collapsable||n.collapsible,depth:t.depth},on:{toggle:function(e){return t.toggleGroup(r)}}}):e("SidebarLink",{attrs:{sidebarDepth:t.sidebarDepth,item:n}})],1)})),0):t._e()}),[],!1,null,null,null);e.default=u.exports},253:function(t,e,n){"use strict";n(241)},256:function(t,e,n){"use strict";n(242)},257:function(t,e,n){"use strict";n(243)},261:function(t,e,n){"use strict";n.r(e);var r=n(239);function i(t,e,n,r){return t("router-link",{props:{to:e,activeClass:"",exactActiveClass:""},class:{active:r,"sidebar-link":!0}},n)}function s(t,e,n,a,o,l=1){return!e||l>o?null:t("ul",{class:"sidebar-sub-headers"},e.map(e=>{const u=Object(r.e)(a,n+"#"+e.slug);return t("li",{class:"sidebar-sub-header"},[i(t,n+"#"+e.slug,e.title,u),s(t,e.children,n,a,o,l+1)])}))}var a={functional:!0,props:["item","sidebarDepth"],render(t,{parent:{$page:e,$site:n,$route:a,$themeConfig:o,$themeLocaleConfig:l},props:{item:u,sidebarDepth:c}}){const p=Object(r.e)(a,u.path),d="auto"===u.type?p||u.children.some(t=>Object(r.e)(a,u.basePath+"#"+t.slug)):p,h="external"===u.type?function(t,e,n){return t("a",{attrs:{href:e,target:"_blank",rel:"noopener noreferrer"},class:{"sidebar-link":!0}},[n,t("OutboundLink")])}(t,u.path,u.title||u.path):i(t,u.path,u.title||u.path,d),f=[e.frontmatter.sidebarDepth,c,l.sidebarDepth,o.sidebarDepth,1].find(t=>void 0!==t),b=l.displayAllHeaders||o.displayAllHeaders;if("auto"===u.type)return[h,s(t,u.children,u.basePath,a,f)];if((d||b)&&u.headers&&!r.d.test(u.path)){return[h,s(t,Object(r.c)(u.headers),u.path,a,f)]}return h}},o=(n(256),n(257),n(14)),l=Object(o.a)(a,void 0,void 0,!1,null,"a68ca4e6",null);e.default=l.exports},266:function(t,e,n){"use strict";n(248)},267:function(t,e,n){"use strict";n.r(e);var r=n(239),i={name:"SidebarGroup",props:["item","open","collapsable","depth"],components:{DropdownTransition:n(249).default},beforeCreate(){this.$options.components.SidebarLinks=n(251).default},methods:{isActive:r.e}},s=(n(266),n(14)),a=Object(s.a)(i,(function(){var t=this,e=t._self._c;return e("div",{staticClass:"sidebar-group",class:[{collapsable:t.collapsable,"is-sub-group":0!==t.depth},"depth-"+t.depth]},[t.item.path?e("router-link",{staticClass:"sidebar-heading clickable",class:{open:t.open,active:t.isActive(t.$route,t.item.path)},attrs:{to:t.item.path},nativeOn:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"open":""}):t._e()]):e("p",{staticClass:"sidebar-heading",class:{open:t.open},on:{click:function(e){return t.$emit("toggle")}}},[e("span",[t._v(t._s(t.item.title))]),t._v(" "),t.collapsable?e("span",{staticClass:"arrow",class:t.open?"open":""}):t._e()]),t._v(" "),e("DropdownTransition",[t.open||!t.collapsable?e("SidebarLinks",{staticClass:"sidebar-group-items",attrs:{items:t.item.children,sidebarDepth:t.item.sidebarDepth,depth:t.depth+1}}):t._e()],1)],1)}),[],!1,null,null,null);e.default=a.exports}}]); \ No newline at end of file diff --git a/assets/js/60.f95023a4.js b/assets/js/60.f95023a4.js new file mode 100644 index 00000000..414992e3 --- /dev/null +++ b/assets/js/60.f95023a4.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[60],{358:function(t,a,s){"use strict";s.r(a);var e=s(14),r=Object(e.a)({},(function(){var t=this,a=t._self._c;return a("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[a("h2",{attrs:{id:"graphqldatafactory"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#graphqldatafactory"}},[t._v("#")]),t._v(" GraphQLDataFactory")]),t._v(" "),a("p",[a("strong",[t._v("Extends Helper")])]),t._v(" "),a("p",[t._v("Helper for managing remote data using GraphQL queries.\nUses data generators like "),a("a",{attrs:{href:"https://github.com/rosiejs/rosie",target:"_blank",rel:"noopener noreferrer"}},[t._v("rosie"),a("OutboundLink")],1),t._v(" or factory girl to create new record.")]),t._v(" "),a("p",[t._v("By defining a factory you set the rules of how data is generated.\nThis data will be saved on server via GraphQL queries and deleted in the end of a test.")]),t._v(" "),a("h2",{attrs:{id:"use-case"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#use-case"}},[t._v("#")]),t._v(" Use Case")]),t._v(" "),a("p",[t._v("Acceptance tests interact with a websites using UI and real browser.\nThere is no way to create data for a specific test other than from user interface.\nThat makes tests slow and fragile. Instead of testing a single feature you need to follow all creation/removal process.")]),t._v(" "),a("p",[t._v("This helper solves this problem.\nIf a web application has GraphQL support, it can be used to create and delete test records.\nBy combining GraphQL with Factories you can easily create records for tests:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("mutateData")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'createUser'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("email")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert@mail.com'")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" user "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("mutateData")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'createUser'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'davert'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("mutateMultiple")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'createPost'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("post_id")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" user"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("To make this work you need")]),t._v(" "),a("ol",[a("li",[t._v("GraphQL endpoint which allows to perform create / delete requests and")]),t._v(" "),a("li",[t._v("define data generation rules")])]),t._v(" "),a("h3",{attrs:{id:"setup"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#setup"}},[t._v("#")]),t._v(" Setup")]),t._v(" "),a("p",[t._v("Install "),a("a",{attrs:{href:"https://github.com/rosiejs/rosie",target:"_blank",rel:"noopener noreferrer"}},[t._v("Rosie"),a("OutboundLink")],1),t._v(" and "),a("a",{attrs:{href:"https://www.npmjs.com/package/faker",target:"_blank",rel:"noopener noreferrer"}},[t._v("Faker"),a("OutboundLink")],1),t._v(" libraries.")]),t._v(" "),a("div",{staticClass:"language-sh extra-class"},[a("pre",{pre:!0,attrs:{class:"language-sh"}},[a("code",[a("span",{pre:!0,attrs:{class:"token function"}},[t._v("npm")]),t._v(" i rosie @faker-js/faker --save-dev\n")])])]),a("p",[t._v("Create a factory file for a resource.")]),t._v(" "),a("p",[t._v("See the example for Users factories:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// tests/factories/users.js")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" Factory "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'rosie'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("Factory"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" faker "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("require")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@faker-js/faker'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Used with a constructor function passed to Factory, so that the final build")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// object matches the necessary pattern to be sent as the variables object.")]),t._v("\nmodule"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("exports "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("new")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token class-name"}},[t._v("Factory")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("buildObj")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("input")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),t._v("buildObj "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// 'attr'-id can be left out depending on the GraphQl resolvers")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("attr")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'name'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" faker"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("name"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("findName")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("attr")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'email'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" faker"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("interact"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("email")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),a("p",[t._v("For more options see "),a("a",{attrs:{href:"https://github.com/rosiejs/rosie",target:"_blank",rel:"noopener noreferrer"}},[t._v("rosie documentation"),a("OutboundLink")],1),t._v(".")]),t._v(" "),a("p",[t._v("Then configure GraphQLDataHelper to match factories and GraphQL schema:")]),t._v(" "),a("h3",{attrs:{id:"configuration"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#configuration"}},[t._v("#")]),t._v(" Configuration")]),t._v(" "),a("p",[t._v("GraphQLDataFactory has following config options:")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("endpoint")]),t._v(": URL for the GraphQL server.")]),t._v(" "),a("li",[a("code",[t._v("cleanup")]),t._v(" (default: true): should inserted records be deleted up after tests")]),t._v(" "),a("li",[a("code",[t._v("factories")]),t._v(": list of defined factories")]),t._v(" "),a("li",[a("code",[t._v("headers")]),t._v(": list of headers")]),t._v(" "),a("li",[a("code",[t._v("GraphQL")]),t._v(": configuration for GraphQL requests.")])]),t._v(" "),a("p",[t._v("See the example:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("GraphQLDataFactory")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("endpoint")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"http://user.com/graphql"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("cleanup")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("headers")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Content-Type'")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'application/json'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'Accept'")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'application/json'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("factories")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("createUser")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("query")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'mutation createUser($input: UserInput!) { createUser(input: $input) { id name }}'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("factory")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./factories/users'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("revert")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("data")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("query")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'mutation deleteUser($id: ID!) { deleteUser(id: $id) }'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("variables")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("id")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" data"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("id"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("p",[t._v("It is required to set GraphQL "),a("code",[t._v("endpoint")]),t._v(" which is the URL to which all the queries go to.\nFactory file is expected to be passed via "),a("code",[t._v("factory")]),t._v(" option.")]),t._v(" "),a("p",[t._v("This Helper uses "),a("a",{attrs:{href:"http://codecept.io/helpers/GraphQL/",target:"_blank",rel:"noopener noreferrer"}},[t._v("GraphQL"),a("OutboundLink")],1),t._v(' helper and accepts its configuration in "GraphQL" section.\nFor instance, to set timeout you should add:')]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"GraphQLDataFactory"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"GraphQL"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v('"timeout"')]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v('"100000"')]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h3",{attrs:{id:"factory"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#factory"}},[t._v("#")]),t._v(" Factory")]),t._v(" "),a("p",[t._v("Factory contains operations -")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("operation")]),t._v(": The operation/mutation that needs to be performed for creating a record in the backend.")])]),t._v(" "),a("p",[t._v("Each operation must have the following:")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("query")]),t._v(": The mutation(query) string. It is expected to use variables to send data with the query.")]),t._v(" "),a("li",[a("code",[t._v("factory")]),t._v(": The path to factory file. The object built by the factory in this file will be passed\nas the 'variables' object to go along with the mutation.")]),t._v(" "),a("li",[a("code",[t._v("revert")]),t._v(": A function called with the data returned when an item is created. The object returned by\nthis function is will be used to later delete the items created. So, make sure RELEVANT DATA IS RETURNED\nwhen a record is created by a mutation.")])]),t._v(" "),a("h3",{attrs:{id:"requests"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#requests"}},[t._v("#")]),t._v(" Requests")]),t._v(" "),a("p",[t._v("Requests can be updated on the fly by using "),a("code",[t._v("onRequest")]),t._v(" function. For instance, you can pass in current session from a cookie.")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[t._v(" "),a("span",{pre:!0,attrs:{class:"token function-variable function"}},[t._v("onRequest")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("async")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("request")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// using global codeceptjs instance")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" cookie "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" codeceptjs"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("container"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("helpers")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'WebDriver'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("grabCookie")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'session'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n request"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("headers "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Cookie")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token template-string"}},[a("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("session=")]),a("span",{pre:!0,attrs:{class:"token interpolation"}},[a("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("${")]),t._v("cookie"),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),a("span",{pre:!0,attrs:{class:"token interpolation-punctuation punctuation"}},[t._v("}")])]),a("span",{pre:!0,attrs:{class:"token template-punctuation string"}},[t._v("`")])]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),a("h3",{attrs:{id:"responses"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#responses"}},[t._v("#")]),t._v(" Responses")]),t._v(" "),a("p",[t._v("By default "),a("code",[t._v("I.mutateData()")]),t._v(" returns a promise with created data as specified in operation query string:")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" client "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("mutateData")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'createClient'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("p",[t._v("Data of created records are collected and used in the end of a test for the cleanup.")]),t._v(" "),a("h2",{attrs:{id:"methods"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#methods"}},[t._v("#")]),t._v(" Methods")]),t._v(" "),a("h3",{attrs:{id:"parameters"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#parameters"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("config")])])]),t._v(" "),a("h3",{attrs:{id:"requestcreate"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#requestcreate"}},[t._v("#")]),t._v(" _requestCreate")]),t._v(" "),a("p",[t._v("Executes request to create a record to the GraphQL endpoint.\nCan be replaced from a custom helper.")]),t._v(" "),a("h4",{attrs:{id:"parameters-2"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#parameters-2"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("operation")]),t._v(" "),a("strong",[a("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),a("OutboundLink")],1)])]),t._v(" "),a("li",[a("code",[t._v("variables")]),t._v(" "),a("strong",[t._v("any")]),t._v(" to be sent along with the query")])]),t._v(" "),a("h3",{attrs:{id:"requestdelete"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#requestdelete"}},[t._v("#")]),t._v(" _requestDelete")]),t._v(" "),a("p",[t._v("Executes request to delete a record to the GraphQL endpoint.\nCan be replaced from a custom helper.")]),t._v(" "),a("h4",{attrs:{id:"parameters-3"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#parameters-3"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("operation")]),t._v(" "),a("strong",[a("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),a("OutboundLink")],1)])]),t._v(" "),a("li",[a("code",[t._v("data")]),t._v(" "),a("strong",[t._v("any")]),t._v(" of the record to be deleted.")])]),t._v(" "),a("h3",{attrs:{id:"mutatedata"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#mutatedata"}},[t._v("#")]),t._v(" mutateData")]),t._v(" "),a("p",[t._v("Generates a new record using factory, sends a GraphQL mutation to store it.")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create a user")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("mutateData")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'createUser'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create user with defined email")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// and receive it when inside async function")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("const")]),t._v(" user "),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("await")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("mutateData")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'createUser'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("email")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user@user.com'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h4",{attrs:{id:"parameters-4"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#parameters-4"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("operation")]),t._v(" "),a("strong",[a("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),a("OutboundLink")],1)]),t._v(" to be performed")]),t._v(" "),a("li",[a("code",[t._v("params")]),t._v(" "),a("strong",[t._v("any")]),t._v(" predefined parameters")])]),t._v(" "),a("h3",{attrs:{id:"mutatemultiple"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#mutatemultiple"}},[t._v("#")]),t._v(" mutateMultiple")]),t._v(" "),a("p",[t._v("Generates bunch of records and sends multiple GraphQL mutation requests to store them.")]),t._v(" "),a("div",{staticClass:"language-js extra-class"},[a("pre",{pre:!0,attrs:{class:"language-js"}},[a("code",[a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create 3 users")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("mutateMultiple")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'createUser'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),a("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// create 3 users of same age")]),t._v("\n"),a("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),a("span",{pre:!0,attrs:{class:"token function"}},[t._v("mutateMultiple")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),a("span",{pre:!0,attrs:{class:"token string"}},[t._v("'createUser'")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("3")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("age")]),a("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token number"}},[t._v("25")]),t._v(" "),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),a("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),a("h4",{attrs:{id:"parameters-5"}},[a("a",{staticClass:"header-anchor",attrs:{href:"#parameters-5"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),a("ul",[a("li",[a("code",[t._v("operation")]),t._v(" "),a("strong",[a("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),a("OutboundLink")],1)])]),t._v(" "),a("li",[a("code",[t._v("times")]),t._v(" "),a("strong",[a("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),a("OutboundLink")],1)])]),t._v(" "),a("li",[a("code",[t._v("params")]),t._v(" "),a("strong",[t._v("any")])])])])}),[],!1,null,null,null);a.default=r.exports}}]); \ No newline at end of file diff --git a/assets/js/61.4122594e.js b/assets/js/61.4122594e.js new file mode 100644 index 00000000..646bc950 --- /dev/null +++ b/assets/js/61.4122594e.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[61],{362:function(s,t,a){"use strict";a.r(t);var e=a(14),n=Object(e.a)({},(function(){var s=this,t=s._self._c;return t("ContentSlotsDistributor",{attrs:{"slot-key":s.$parent.slotKey}},[t("h2",{attrs:{id:"jsonresponse"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#jsonresponse"}},[s._v("#")]),s._v(" JSONResponse")]),s._v(" "),t("p",[t("strong",[s._v("Extends Helper")])]),s._v(" "),t("p",[s._v("This helper allows performing assertions on JSON responses paired with following helpers:")]),s._v(" "),t("ul",[t("li",[s._v("REST")]),s._v(" "),t("li",[s._v("GraphQL")]),s._v(" "),t("li",[s._v("Playwright")])]),s._v(" "),t("p",[s._v("It can check status codes, response data, response structure.")]),s._v(" "),t("h2",{attrs:{id:"configuration"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#configuration"}},[s._v("#")]),s._v(" Configuration")]),s._v(" "),t("ul",[t("li",[t("code",[s._v("requestHelper")]),s._v(" - a helper which will perform requests. "),t("code",[s._v("REST")]),s._v(" by default, also "),t("code",[s._v("Playwright")]),s._v(" or "),t("code",[s._v("GraphQL")]),s._v(" can be used. Custom helpers must have "),t("code",[s._v("onResponse")]),s._v(" hook in their config, which will be executed when request is performed.")])]),s._v(" "),t("h3",{attrs:{id:"examples"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#examples"}},[s._v("#")]),s._v(" Examples")]),s._v(" "),t("p",[s._v("Zero-configuration when paired with REST:")]),s._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// inside codecept.conf.js")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("helpers")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("REST")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("endpoint")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'http://site.com/api'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("JSONResponse")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),t("p",[s._v("Explicitly setting request helper if you use "),t("code",[s._v("makeApiRequest")]),s._v(" of Playwright to perform requests and not paired REST:")]),s._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// inside codecept.conf.js")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// ...")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("helpers")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("Playwright")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("url")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'https://localhost'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("browser")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'chromium'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("JSONResponse")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("requestHelper")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'Playwright'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v("\n")])])]),t("h2",{attrs:{id:"access-from-helpers"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#access-from-helpers"}},[s._v("#")]),s._v(" Access From Helpers")]),s._v(" "),t("p",[s._v("If you plan to add custom assertions it is recommended to create a helper that will retrieve response object from JSONResponse:")]),s._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// inside custom helper")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("const")]),s._v(" response "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("this")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("helpers"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("JSONResponse"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("response"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("h2",{attrs:{id:"methods"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#methods"}},[s._v("#")]),s._v(" Methods")]),s._v(" "),t("h3",{attrs:{id:"parameters"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#parameters"}},[s._v("#")]),s._v(" Parameters")]),s._v(" "),t("ul",[t("li",[t("code",[s._v("config")])])]),s._v(" "),t("h3",{attrs:{id:"dontseeresponsecodeis"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#dontseeresponsecodeis"}},[s._v("#")]),s._v(" dontSeeResponseCodeIs")]),s._v(" "),t("p",[s._v("Checks that response code is not equal to the provided one")]),s._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("I")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("dontSeeResponseCodeIs")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("500")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("h4",{attrs:{id:"parameters-2"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#parameters-2"}},[s._v("#")]),s._v(" Parameters")]),s._v(" "),t("ul",[t("li",[t("code",[s._v("code")]),s._v(" "),t("strong",[t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[s._v("number"),t("OutboundLink")],1)])])]),s._v(" "),t("h3",{attrs:{id:"dontseeresponsecontainsjson"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#dontseeresponsecontainsjson"}},[s._v("#")]),s._v(" dontSeeResponseContainsJson")]),s._v(" "),t("p",[s._v("Checks for deep inclusion of a provided json in a response data.")]),s._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// response.data == { data: { user: 1 } }")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("I")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("dontSeeResponseContainsJson")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("user")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("2")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("p",[s._v("If an array is received, checks that no element of array contains json:")]),s._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// response.data == [{ user: 1 }, { user: 3 }]")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("I")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("dontSeeResponseContainsJson")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("user")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("2")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("h4",{attrs:{id:"parameters-3"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#parameters-3"}},[s._v("#")]),s._v(" Parameters")]),s._v(" "),t("ul",[t("li",[t("code",[s._v("json")]),s._v(" "),t("strong",[t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[s._v("object"),t("OutboundLink")],1)])])]),s._v(" "),t("h3",{attrs:{id:"seeresponsecodeis"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#seeresponsecodeis"}},[s._v("#")]),s._v(" seeResponseCodeIs")]),s._v(" "),t("p",[s._v("Checks that response code is equal to the provided one")]),s._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("I")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("seeResponseCodeIs")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("200")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("h4",{attrs:{id:"parameters-4"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#parameters-4"}},[s._v("#")]),s._v(" Parameters")]),s._v(" "),t("ul",[t("li",[t("code",[s._v("code")]),s._v(" "),t("strong",[t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[s._v("number"),t("OutboundLink")],1)])])]),s._v(" "),t("h3",{attrs:{id:"seeresponsecodeisclienterror"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#seeresponsecodeisclienterror"}},[s._v("#")]),s._v(" seeResponseCodeIsClientError")]),s._v(" "),t("p",[s._v("Checks that the response code is 4xx")]),s._v(" "),t("h3",{attrs:{id:"seeresponsecodeisredirection"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#seeresponsecodeisredirection"}},[s._v("#")]),s._v(" seeResponseCodeIsRedirection")]),s._v(" "),t("p",[s._v("Checks that the response code is 3xx")]),s._v(" "),t("h3",{attrs:{id:"seeresponsecodeisservererror"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#seeresponsecodeisservererror"}},[s._v("#")]),s._v(" seeResponseCodeIsServerError")]),s._v(" "),t("p",[s._v("Checks that the response code is 5xx")]),s._v(" "),t("h3",{attrs:{id:"seeresponsecodeissuccessful"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#seeresponsecodeissuccessful"}},[s._v("#")]),s._v(" seeResponseCodeIsSuccessful")]),s._v(" "),t("p",[s._v("Checks that the response code is 2xx\nUse it instead of seeResponseCodeIs(200) if server can return 204 instead.")]),s._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("I")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("seeResponseCodeIsSuccessful")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("h3",{attrs:{id:"seeresponsecontainsjson"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#seeresponsecontainsjson"}},[s._v("#")]),s._v(" seeResponseContainsJson")]),s._v(" "),t("p",[s._v("Checks for deep inclusion of a provided json in a response data.")]),s._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// response.data == { user: { name: 'jon', email: 'jon@doe.com' } }")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("I")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("seeResponseContainsJson")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("user")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("email")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'jon@doe.com'")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("p",[s._v("If an array is received, checks that at least one element contains JSON")]),s._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// response.data == [{ user: { name: 'jon', email: 'jon@doe.com' } }]")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("I")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("seeResponseContainsJson")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("user")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("email")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'jon@doe.com'")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("h4",{attrs:{id:"parameters-5"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#parameters-5"}},[s._v("#")]),s._v(" Parameters")]),s._v(" "),t("ul",[t("li",[t("code",[s._v("json")]),s._v(" "),t("strong",[t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[s._v("object"),t("OutboundLink")],1)])])]),s._v(" "),t("h3",{attrs:{id:"seeresponsecontainskeys"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#seeresponsecontainskeys"}},[s._v("#")]),s._v(" seeResponseContainsKeys")]),s._v(" "),t("p",[s._v("Checks for deep inclusion of a provided json in a response data.")]),s._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// response.data == { user: { name: 'jon', email: 'jon@doe.com' } }")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("I")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("seeResponseContainsKeys")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'user'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("p",[s._v("If an array is received, check is performed for each element of array:")]),s._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// response.data == [{ user: 'jon' }, { user: 'matt'}]")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("I")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("seeResponseContainsKeys")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'user'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("h4",{attrs:{id:"parameters-6"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#parameters-6"}},[s._v("#")]),s._v(" Parameters")]),s._v(" "),t("ul",[t("li",[t("code",[s._v("keys")]),s._v(" "),t("strong",[t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array",target:"_blank",rel:"noopener noreferrer"}},[s._v("array"),t("OutboundLink")],1)])])]),s._v(" "),t("h3",{attrs:{id:"seeresponseequals"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#seeresponseequals"}},[s._v("#")]),s._v(" seeResponseEquals")]),s._v(" "),t("p",[s._v("Checks that response data equals to expected:")]),s._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// response.data is { error: 'Not allowed' }")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("I")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("seeResponseEquals")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("error")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'Not allowed'")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n")])])]),t("h4",{attrs:{id:"parameters-7"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#parameters-7"}},[s._v("#")]),s._v(" Parameters")]),s._v(" "),t("ul",[t("li",[t("code",[s._v("resp")]),s._v(" "),t("strong",[t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[s._v("object"),t("OutboundLink")],1)])])]),s._v(" "),t("h3",{attrs:{id:"seeresponsematchesjsonschema"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#seeresponsematchesjsonschema"}},[s._v("#")]),s._v(" seeResponseMatchesJsonSchema")]),s._v(" "),t("p",[s._v("Validates JSON structure of response using "),t("a",{attrs:{href:"https://joi.dev",target:"_blank",rel:"noopener noreferrer"}},[s._v("joi library"),t("OutboundLink")],1),s._v(".\nSee "),t("a",{attrs:{href:"https://joi.dev/api/",target:"_blank",rel:"noopener noreferrer"}},[s._v("joi API"),t("OutboundLink")],1),s._v(" for complete reference on usage.")]),s._v(" "),t("p",[s._v("Use pre-initialized joi instance by passing function callback:")]),s._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// response.data is { name: 'jon', id: 1 }")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("I")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("seeResponseMatchesJsonSchema")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token parameter"}},[s._v("joi")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=>")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("return")]),s._v(" joi"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("object")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("name")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" joi"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("string")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("id")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" joi"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("number")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token comment"}},[s._v("// or pass a valid schema")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token keyword"}},[s._v("const")]),s._v(" joi "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("require")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'joi'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n\n"),t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("I")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("seeResponseMatchesJsonSchema")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("joi"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("object")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("name")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" joi"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("string")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token literal-property property"}},[s._v("id")]),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v(":")]),s._v(" joi"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("number")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("h4",{attrs:{id:"parameters-8"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#parameters-8"}},[s._v("#")]),s._v(" Parameters")]),s._v(" "),t("ul",[t("li",[t("code",[s._v("fnOrSchema")]),s._v(" "),t("strong",[s._v("any")])])]),s._v(" "),t("h3",{attrs:{id:"seeresponsevalidbycallback"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#seeresponsevalidbycallback"}},[s._v("#")]),s._v(" seeResponseValidByCallback")]),s._v(" "),t("p",[s._v("Executes a callback function passing in "),t("code",[s._v("response")]),s._v(" object and chai assertions with "),t("code",[s._v("expect")]),s._v("\nUse it to perform custom checks of response data")]),s._v(" "),t("div",{staticClass:"language-js extra-class"},[t("pre",{pre:!0,attrs:{class:"language-js"}},[t("code",[t("span",{pre:!0,attrs:{class:"token constant"}},[s._v("I")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("seeResponseValidByCallback")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token parameter"}},[t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v(" data"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" status"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" expect "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")])]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token operator"}},[s._v("=>")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("{")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("expect")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("status"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("to"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("eql")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token number"}},[s._v("200")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n "),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("expect")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),s._v("data"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("keys"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),s._v("to"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(".")]),t("span",{pre:!0,attrs:{class:"token function"}},[s._v("include")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("(")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("[")]),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'user'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(",")]),s._v(" "),t("span",{pre:!0,attrs:{class:"token string"}},[s._v("'company'")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("]")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n"),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v("}")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(")")]),t("span",{pre:!0,attrs:{class:"token punctuation"}},[s._v(";")]),s._v("\n")])])]),t("h4",{attrs:{id:"parameters-9"}},[t("a",{staticClass:"header-anchor",attrs:{href:"#parameters-9"}},[s._v("#")]),s._v(" Parameters")]),s._v(" "),t("ul",[t("li",[t("code",[s._v("fn")]),s._v(" "),t("strong",[t("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Statements/function",target:"_blank",rel:"noopener noreferrer"}},[s._v("function"),t("OutboundLink")],1)])])])])}),[],!1,null,null,null);t.default=n.exports}}]); \ No newline at end of file diff --git a/assets/js/62.169b5f14.js b/assets/js/62.169b5f14.js new file mode 100644 index 00000000..081d6cfe --- /dev/null +++ b/assets/js/62.169b5f14.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[62],{363:function(t,n,s){"use strict";s.r(n);var e=s(14),o=Object(e.a)({},(function(){return(0,this._self._c)("ContentSlotsDistributor",{attrs:{"slot-key":this.$parent.slotKey}})}),[],!1,null,null,null);n.default=o.exports}}]); \ No newline at end of file diff --git a/assets/js/63.8cc4f70f.js b/assets/js/63.8cc4f70f.js new file mode 100644 index 00000000..c341cd3b --- /dev/null +++ b/assets/js/63.8cc4f70f.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[63],{376:function(t,s,a){"use strict";a.r(s);var n=a(14),e=Object(n.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h1",{attrs:{id:"mockrequest"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#mockrequest"}},[t._v("#")]),t._v(" MockRequest")]),t._v(" "),s("h2",{attrs:{id:"mockrequest-2"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#mockrequest-2"}},[t._v("#")]),t._v(" MockRequest")]),t._v(" "),s("p",[t._v("This helper allows to "),s("strong",[t._v("mock requests while running tests in Puppeteer or WebDriver")]),t._v(".\nFor instance, you can block calls to 3rd-party services like Google Analytics, CDNs.\nAnother way of using is to emulate requests from server by passing prepared data.")]),t._v(" "),s("p",[t._v("MockRequest helper works in these "),s("a",{attrs:{href:"https://netflix.github.io/pollyjs/#/configuration?id=mode",target:"_blank",rel:"noopener noreferrer"}},[t._v("modes"),s("OutboundLink")],1),t._v(":")]),t._v(" "),s("ul",[s("li",[t._v("passthrough (default) - mock prefefined HTTP requests")]),t._v(" "),s("li",[t._v("record - record all requests into a file")]),t._v(" "),s("li",[t._v("replay - replay all recorded requests from a file")])]),t._v(" "),s("p",[t._v("Combining record/replay modes allows testing websites with large datasets.")]),t._v(" "),s("p",[t._v("To use in passthrough mode set rules to mock requests and they will be automatically intercepted and replaced:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// default mode")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'GET'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/users'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'[]'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("In record-replay mode start mocking to make HTTP requests recorded/replayed, and stop when you don't need to block requests anymore:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// record or replay all XHR for /users page")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("startMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/users'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("stopMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"installations"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#installations"}},[t._v("#")]),t._v(" Installations")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",[s("code",[t._v("npm i @codeceptjs/mock-request --save-dev\n")])])]),s("p",[t._v("Requires Puppeteer helper or WebDriver helper enabled")]),t._v(" "),s("h3",{attrs:{id:"configuration"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#configuration"}},[t._v("#")]),t._v(" Configuration")]),t._v(" "),s("h4",{attrs:{id:"with-puppeteer"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#with-puppeteer"}},[t._v("#")]),t._v(" With Puppeteer")]),t._v(" "),s("p",[t._v("Enable helper in config file:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Puppeteer")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// regular Puppeteer config here")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("MockRequestHelper")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@codeceptjs/mock-request'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[s("a",{attrs:{href:"https://netflix.github.io/pollyjs/#/configuration?id=configuration",target:"_blank",rel:"noopener noreferrer"}},[t._v("Polly config options"),s("OutboundLink")],1),t._v(" can be passed as well:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// sample options")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("MockRequestHelper")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@codeceptjs/mock-request'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("mode")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" record"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("recordIfMissing")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("recordFailedRequests")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("expiresIn")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("null")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("persisterOptions")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("keepUnusedRequests")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("fs")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("recordingsDir")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'./data/requests'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("hr"),t._v(" "),s("p",[s("strong",[t._v("TROUBLESHOOTING")]),t._v(": Puppeteer does not mock requests in headless mode:")]),t._v(" "),s("p",[t._v("Problem: request mocking does not work and in debug mode you see this in output:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",[s("code",[t._v("Access to fetch at {url} from origin {url} has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.\n")])])]),s("p",[t._v("Solution: update Puppeteer config to include "),s("code",[t._v("--disable-web-security")]),t._v(" arguments:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Puppeteer")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("show")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("chrome")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("args")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'--disable-web-security'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n")])])]),s("hr"),t._v(" "),s("h4",{attrs:{id:"with-webdriver"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#with-webdriver"}},[t._v("#")]),t._v(" With WebDriver")]),t._v(" "),s("p",[t._v("This helper partially works with WebDriver. It can intercept and mock requests "),s("strong",[t._v("only on already loaded page")]),t._v(".")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("WebDriver")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// regular WebDriver config here")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("MockRequestHelper")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@codeceptjs/mock-request'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("blockquote",[s("p",[t._v("Record/Replay mode is not tested in WebDriver but technically can work with "),s("a",{attrs:{href:"https://netflix.github.io/pollyjs/#/examples?id=rest-persister",target:"_blank",rel:"noopener noreferrer"}},[t._v("REST Persister"),s("OutboundLink")],1)])]),t._v(" "),s("h2",{attrs:{id:"usage"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#usage"}},[t._v("#")]),t._v(" Usage")]),t._v(" "),s("h3",{attrs:{id:"👻-mock-requests"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#👻-mock-requests"}},[t._v("#")]),t._v(" 👻 Mock Requests")]),t._v(" "),s("p",[t._v("To intercept API requests and mock them use following API")]),t._v(" "),s("ul",[s("li",[s("a",{attrs:{href:"#startMocking"}},[t._v("startMocking()")]),t._v(" - to enable request interception")]),t._v(" "),s("li",[s("a",{attrs:{href:"#mockRequest"}},[t._v("mockRequest()")]),t._v(" - to define mock in a simple way")]),t._v(" "),s("li",[s("a",{attrs:{href:"#mockServer"}},[t._v("mockServer()")]),t._v(" - to use PollyJS server API to define complex mocks")]),t._v(" "),s("li",[s("a",{attrs:{href:"#stopMocking"}},[t._v("stopMocking()")]),t._v(" - to stop intercepting requests and disable mocks.")])]),t._v(" "),s("p",[t._v("Calling "),s("code",[t._v("mockRequest")]),t._v(" or "),s("code",[t._v("mockServer")]),t._v(" will start mocking, if it was not enabled yet.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("startMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// optionally")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/google-analytics/*path'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// return an empty successful response ")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'GET'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/users'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// mock users api")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockServer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("server")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n server"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://server.com/api/users*'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("intercept")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("req"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" res")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("status")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("json")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("users"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("click")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("'Get users"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("stopMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"📼-record-replay"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#📼-record-replay"}},[t._v("#")]),t._v(" 📼 Record & Replay")]),t._v(" "),s("blockquote",[s("p",[t._v("At this moment works only with Puppeteer")])]),t._v(" "),s("p",[t._v("Record & Replay mode allows you to record all xhr & fetch requests and save them to file.\nOn next runs those requests can be replayed.\nBy default, it stores all passed requests, but this behavior can be customized with "),s("code",[t._v("I.mockServer")])]),t._v(" "),s("p",[t._v("Set mode via enironment variable, "),s("code",[t._v("replay")]),t._v(" mode by default:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// enable replay mode")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("Puppeteer")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// regular Puppeteer config here")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("MockRequest")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("require")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'@codeceptjs/mock-request'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("mode")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" process"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("env"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("MOCK_MODE")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("||")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'replay'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("p",[t._v("Interactions between "),s("code",[t._v("I.startMocking()")]),t._v(" and "),s("code",[t._v("I.stopMocking()")]),t._v(" will be recorded and saved to "),s("code",[t._v("data/requests")]),t._v(" directory.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("startMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// record requests under 'Test' name")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("startMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'users'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// record requests under 'users' name")]),t._v("\n")])])]),s("p",[t._v("Use "),s("code",[t._v("I.mockServer()")]),t._v(" to customize which requests should be recorded and under which name:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("startMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockServer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("server")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// mock request only from ap1.com and api2.com and")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// store recording into two different files")]),t._v("\n server"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://api1.com/*'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("passthrough")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("recordingName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'api1'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n server"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://api2.com/*'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("passthrough")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("recordingName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'api2'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("To stop request recording/replaying use "),s("code",[t._v("I.stopMocking()")]),t._v(".")]),t._v(" "),s("p",[t._v('🎥 To record HTTP interactions execute tests with MOCK_MODE environment variable set as "record":')]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",[s("code",[t._v("MOCK_MODE=record npx codeceptjs run --debug\n")])])]),s("p",[t._v("📼 To replay them launch tests without environment variable:")]),t._v(" "),s("div",{staticClass:"language- extra-class"},[s("pre",[s("code",[t._v("npx codeceptjs run --debug\n")])])]),s("h3",{attrs:{id:"parameters"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#parameters"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("config")])])]),t._v(" "),s("h3",{attrs:{id:"flushmocking"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#flushmocking"}},[t._v("#")]),t._v(" flushMocking")]),t._v(" "),s("p",[t._v("Waits for all requests handled by MockRequests to be resolved:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("flushMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"mockrequest-3"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#mockrequest-3"}},[t._v("#")]),t._v(" mockRequest")]),t._v(" "),s("p",[t._v("Mock response status")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'GET'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/users'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'ANY'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/secretsRoutes/*'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("403")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'POST'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/secrets'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("secrets")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'fakeSecrets'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'GET'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/users/1'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("404")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'User not found'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("Multiple requests")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockRequest")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'GET'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/secrets'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/v2/secrets'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("403")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h4",{attrs:{id:"parameters-2"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#parameters-2"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("method")]),t._v(" "),s("strong",[s("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),s("OutboundLink")],1)]),t._v(" request method. Can be "),s("code",[t._v("GET")]),t._v(", "),s("code",[t._v("POST")]),t._v(", "),s("code",[t._v("PUT")]),t._v(", etc or "),s("code",[t._v("ANY")]),t._v(".")]),t._v(" "),s("li",[s("code",[t._v("oneOrMoreUrls")]),t._v(" "),s("strong",[t._v("("),s("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),s("OutboundLink")],1),t._v(" | "),s("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array",target:"_blank",rel:"noopener noreferrer"}},[t._v("Array"),s("OutboundLink")],1),t._v("<"),s("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),s("OutboundLink")],1),t._v(">)")]),t._v(" url(s) to mock. Can be exact URL, a pattern, or an array of URLs.")]),t._v(" "),s("li",[s("code",[t._v("dataOrStatusCode")]),t._v(" "),s("strong",[t._v("("),s("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),s("OutboundLink")],1),t._v(" | "),s("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),s("OutboundLink")],1),t._v(" | "),s("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),s("OutboundLink")],1),t._v(")")]),t._v(" status code when number provided. A response body otherwise")]),t._v(" "),s("li",[s("code",[t._v("additionalData")]),t._v(" "),s("strong",[t._v("("),s("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),s("OutboundLink")],1),t._v(" | "),s("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),s("OutboundLink")],1),t._v(")")]),t._v(" response body when a status code is set by previous parameter. (optional, default "),s("code",[t._v("null")]),t._v(")")])]),t._v(" "),s("h3",{attrs:{id:"mockserver"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#mockserver"}},[t._v("#")]),t._v(" mockServer")]),t._v(" "),s("p",[t._v("Use PollyJS "),s("a",{attrs:{href:"https://netflix.github.io/pollyjs/#/server/overview",target:"_blank",rel:"noopener noreferrer"}},[t._v("Server Routes API"),s("OutboundLink")],1),t._v(" to declare mocks via callback function:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockServer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("server")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// basic usage")]),t._v("\n server"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/v2/users'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("intercept")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("req"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" res")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n res"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("sendStatus")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("json")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" users "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v('// passthrough requests to "/api/v2"')]),t._v("\n server"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("get")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/v1'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("passthrough")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("In record replay mode you can define which routes should be recorded and where to store them:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("startMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'mock'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("mockServer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("server")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=>")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// record requests from cdn1.com and save them to data/recording/xml")]),t._v("\n server"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://cdn1.com/*'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("passthrough")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("recordingName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'xml'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n \n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// record requests from cdn2.com and save them to data/recording/svg")]),t._v("\n server"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://cdn2.com/*'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("passthrough")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("recordingName")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'svg'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// record requests from /api and save them to data/recording/mock (default)")]),t._v("\n server"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("any")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/*'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("passthrough")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h4",{attrs:{id:"parameters-3"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#parameters-3"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("configFn")])])]),t._v(" "),s("h3",{attrs:{id:"passthroughmocking"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#passthroughmocking"}},[t._v("#")]),t._v(" passthroughMocking")]),t._v(" "),s("p",[t._v("Forces passthrough mode for mocking.\nRequires mocking to be started.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("passthroughMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"recordmocking"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#recordmocking"}},[t._v("#")]),t._v(" recordMocking")]),t._v(" "),s("p",[t._v("Forces record mode for mocking.\nRequires mocking to be started.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("recordMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"replaymocking"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#replaymocking"}},[t._v("#")]),t._v(" replayMocking")]),t._v(" "),s("p",[t._v("Forces replay mode for mocking.\nRequires mocking to be started.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("replayMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h3",{attrs:{id:"startmocking"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#startmocking"}},[t._v("#")]),t._v(" startMocking")]),t._v(" "),s("p",[t._v("Starts mocking of http requests.\nIn record mode starts recording of all requests.\nIn replay mode blocks all requests and replaces them with saved.")]),t._v(" "),s("p",[t._v("If inside one test you plan to record/replay requests in several places, provide "),s("a",{attrs:{href:"https://netflix.github.io/pollyjs/#/api?id=recordingname",target:"_blank",rel:"noopener noreferrer"}},[t._v("recording name"),s("OutboundLink")],1),t._v(" as the parameter.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// start mocking requests for a test")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("startMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" \n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// start mocking requests for main page")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("startMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'main-page'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// do actions")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("stopMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("startMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'login-page'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("p",[t._v("To update "),s("a",{attrs:{href:"https://netflix.github.io/pollyjs/#/configuration",target:"_blank",rel:"noopener noreferrer"}},[t._v("PollyJS configuration"),s("OutboundLink")],1),t._v(" use secon argument:")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// change mode")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("startMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'comments'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("mode")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'replay'")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// override config")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("startMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'users-loaded'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("recordFailedRequests")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("true")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v("\n")])])]),s("h4",{attrs:{id:"parameters-4"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#parameters-4"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("title")]),t._v(" "),s("strong",[t._v("any")]),t._v(" (optional, default "),s("code",[t._v("'Test'")]),t._v(")")]),t._v(" "),s("li",[s("code",[t._v("config")]),t._v(" (optional, default "),s("code",[t._v("{}")]),t._v(")")])]),t._v(" "),s("h3",{attrs:{id:"stopmocking"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#stopmocking"}},[t._v("#")]),t._v(" stopMocking")]),t._v(" "),s("p",[t._v("Stops mocking requests.\nMust be called to save recorded requests into faile.")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("stopMocking")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/64.458062ef.js b/assets/js/64.458062ef.js new file mode 100644 index 00000000..00bd1e8a --- /dev/null +++ b/assets/js/64.458062ef.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[64],{361:function(t,s,a){"use strict";a.r(s);var r=a(14),e=Object(r.a)({},(function(){var t=this,s=t._self._c;return s("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[s("h2",{attrs:{id:"mockserver"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#mockserver"}},[t._v("#")]),t._v(" MockServer")]),t._v(" "),s("p",[t._v("MockServer")]),t._v(" "),s("p",[t._v("The MockServer Helper in CodeceptJS empowers you to mock any server or service via HTTP or HTTPS, making it an excellent tool for simulating REST endpoints and other HTTP-based APIs.")]),t._v(" "),s("h2",{attrs:{id:"configuration"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#configuration"}},[t._v("#")]),t._v(" Configuration")]),t._v(" "),s("p",[t._v("This helper should be configured in codecept.conf.(js|ts)")]),t._v(" "),s("p",[t._v("Type: "),s("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),s("OutboundLink")],1)]),t._v(" "),s("h3",{attrs:{id:"properties"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#properties"}},[t._v("#")]),t._v(" Properties")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("port")]),t._v(" "),s("strong",[s("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),s("OutboundLink")],1),t._v("?")]),t._v(" Mock server port")]),t._v(" "),s("li",[s("code",[t._v("host")]),t._v(" "),s("strong",[s("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),s("OutboundLink")],1),t._v("?")]),t._v(" Mock server host")]),t._v(" "),s("li",[s("code",[t._v("httpsOpts")]),t._v(" "),s("strong",[s("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),s("OutboundLink")],1),t._v("?")]),t._v(" key & cert values are the paths to .key and .crt files")])]),t._v(" "),s("h4",{attrs:{id:"examples"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#examples"}},[t._v("#")]),t._v(" Examples")]),t._v(" "),s("p",[t._v("You can seamlessly integrate MockServer with other helpers like REST or Playwright. Here's a configuration example inside the "),s("code",[t._v("codecept.conf.js")]),t._v(" file:")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("helpers")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("REST")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v("...")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("MockServer")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// default mock server config")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("port")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("9393")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("host")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'0.0.0.0'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("httpsOpts")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("key")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("cert")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("''")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n")])])]),s("h4",{attrs:{id:"adding-interactions"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#adding-interactions"}},[t._v("#")]),t._v(" Adding Interactions")]),t._v(" "),s("p",[t._v("Interactions add behavior to the mock server. Use the "),s("code",[t._v("I.addInteractionToMockServer()")]),t._v(" method to include interactions. It takes an interaction object as an argument, containing request and response details.")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("addInteractionToMockServer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("request")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("method")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'GET'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("path")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/hello'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("response")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("status")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("body")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'say'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'hello to mock server'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h4",{attrs:{id:"request-matching"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#request-matching"}},[t._v("#")]),t._v(" Request Matching")]),t._v(" "),s("p",[t._v("When a real request is sent to the mock server, it matches the received request with the interactions. If a match is found, it returns the specified response; otherwise, a 404 status code is returned.")]),t._v(" "),s("ul",[s("li",[t._v("Strong match on HTTP Method, Path, Query Params & JSON body.")]),t._v(" "),s("li",[t._v("Loose match on Headers.")])]),t._v(" "),s("h5",{attrs:{id:"strong-match-on-query-params"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#strong-match-on-query-params"}},[t._v("#")]),t._v(" Strong Match on Query Params")]),t._v(" "),s("p",[t._v("You can send different responses based on query parameters:")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("addInteractionToMockServer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("request")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("method")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'GET'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("path")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/users'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("queryParams")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("1")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("response")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("status")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("body")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user 1'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("addInteractionToMockServer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("request")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("method")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'GET'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("path")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/users'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("queryParams")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("response")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("status")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("body")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'user 2'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ul",[s("li",[t._v("GET to "),s("code",[t._v("/api/users?id=1")]),t._v(" will return 'user 1'.")]),t._v(" "),s("li",[t._v("GET to "),s("code",[t._v("/api/users?id=2")]),t._v(" will return 'user 2'.")]),t._v(" "),s("li",[t._v("For all other requests, it returns a 404 status code.")])]),t._v(" "),s("h5",{attrs:{id:"loose-match-on-body"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#loose-match-on-body"}},[t._v("#")]),t._v(" Loose Match on Body")]),t._v(" "),s("p",[t._v("When "),s("code",[t._v("strict")]),t._v(" is set to false, it performs a loose match on query params and response body:")]),t._v(" "),s("div",{staticClass:"language-javascript extra-class"},[s("pre",{pre:!0,attrs:{class:"language-javascript"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("addInteractionToMockServer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("strict")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token boolean"}},[t._v("false")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("request")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("method")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'POST'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("path")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/users'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("body")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'john'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("response")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("status")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("ul",[s("li",[t._v("POST to "),s("code",[t._v("/api/users")]),t._v(" with the body containing "),s("code",[t._v("name")]),t._v(" as 'john' will return a 200 status code.")]),t._v(" "),s("li",[t._v("POST to "),s("code",[t._v("/api/users")]),t._v(" without the "),s("code",[t._v("name")]),t._v(" property in the body will return a 404 status code.")])]),t._v(" "),s("p",[t._v("Happy testing with MockServer in CodeceptJS! 🚀")]),t._v(" "),s("h2",{attrs:{id:"methods"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#methods"}},[t._v("#")]),t._v(" Methods")]),t._v(" "),s("h3",{attrs:{id:"parameters"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#parameters"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("passedConfig")])])]),t._v(" "),s("h3",{attrs:{id:"addinteractiontomockserver"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#addinteractiontomockserver"}},[t._v("#")]),t._v(" addInteractionToMockServer")]),t._v(" "),s("p",[t._v("An interaction adds behavior to the mock server")]),t._v(" "),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("addInteractionToMockServer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("request")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("method")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'GET'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("path")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/hello'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("response")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("status")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("body")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'say'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'hello to mock server'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("div",{staticClass:"language-js extra-class"},[s("pre",{pre:!0,attrs:{class:"language-js"}},[s("code",[s("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// with query params")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),s("span",{pre:!0,attrs:{class:"token function"}},[t._v("addInteractionToMockServer")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("request")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("method")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'GET'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("path")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/api/hello'")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("queryParams")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("id")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("2")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("response")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("status")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token number"}},[t._v("200")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("body")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token string-property property"}},[t._v("'say'")]),s("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),s("span",{pre:!0,attrs:{class:"token string"}},[t._v("'hello to mock server'")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n "),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),t._v("\n"),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),s("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),s("h4",{attrs:{id:"parameters-2"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#parameters-2"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("interaction")]),t._v(" "),s("strong",[t._v("(CodeceptJS.MockInteraction | "),s("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),s("OutboundLink")],1),t._v(")")]),t._v(" add behavior to the mock server")])]),t._v(" "),s("p",[t._v("Returns "),s("strong",[t._v("any")]),t._v(" void")]),t._v(" "),s("h3",{attrs:{id:"startmockserver"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#startmockserver"}},[t._v("#")]),t._v(" startMockServer")]),t._v(" "),s("p",[t._v("Start the mock server")]),t._v(" "),s("h4",{attrs:{id:"parameters-3"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#parameters-3"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),s("ul",[s("li",[s("code",[t._v("port")]),t._v(" "),s("strong",[s("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Number",target:"_blank",rel:"noopener noreferrer"}},[t._v("number"),s("OutboundLink")],1),t._v("?")]),t._v(" start the mock server with given port")])]),t._v(" "),s("p",[t._v("Returns "),s("strong",[t._v("any")]),t._v(" void")]),t._v(" "),s("h3",{attrs:{id:"stopmockserver"}},[s("a",{staticClass:"header-anchor",attrs:{href:"#stopmockserver"}},[t._v("#")]),t._v(" stopMockServer")]),t._v(" "),s("p",[t._v("Stop the mock server")]),t._v(" "),s("p",[t._v("Returns "),s("strong",[t._v("any")]),t._v(" void")])])}),[],!1,null,null,null);s.default=e.exports}}]); \ No newline at end of file diff --git a/assets/js/65.7f8c92a5.js b/assets/js/65.7f8c92a5.js new file mode 100644 index 00000000..73d4bd53 --- /dev/null +++ b/assets/js/65.7f8c92a5.js @@ -0,0 +1 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[65],{366:function(t,e,a){"use strict";a.r(e);var s=a(14),r=Object(s.a)({},(function(){var t=this,e=t._self._c;return e("ContentSlotsDistributor",{attrs:{"slot-key":t.$parent.slotKey}},[e("h2",{attrs:{id:"nightmare"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#nightmare"}},[t._v("#")]),t._v(" Nightmare")]),t._v(" "),e("p",[e("strong",[t._v("Extends Helper")])]),t._v(" "),e("p",[t._v("Nightmare helper wraps "),e("a",{attrs:{href:"https://github.com/segmentio/nightmare",target:"_blank",rel:"noopener noreferrer"}},[t._v("Nightmare"),e("OutboundLink")],1),t._v(" library to provide\nfastest headless testing using Electron engine. Unlike Selenium-based drivers this uses\nChromium-based browser with Electron with lots of client side scripts, thus should be less stable and\nless trusted.")]),t._v(" "),e("p",[t._v("Requires "),e("code",[t._v("nightmare")]),t._v(" package to be installed.")]),t._v(" "),e("h2",{attrs:{id:"configuration"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#configuration"}},[t._v("#")]),t._v(" Configuration")]),t._v(" "),e("p",[t._v("This helper should be configured in codecept.conf.ts or codecept.conf.js")]),t._v(" "),e("ul",[e("li",[e("p",[e("code",[t._v("url")]),t._v(" - base url of website to be tested")])]),t._v(" "),e("li",[e("p",[e("code",[t._v("restart")]),t._v(" - restart browser between tests.")])]),t._v(" "),e("li",[e("p",[e("code",[t._v("disableScreenshots")]),t._v(" - don't save screenshot on failure.")])]),t._v(" "),e("li",[e("p",[e("code",[t._v("uniqueScreenshotNames")]),t._v(" - option to prevent screenshot override if you have scenarios with the same name in different suites.")])]),t._v(" "),e("li",[e("p",[e("code",[t._v("fullPageScreenshots")]),t._v(" - make full page screenshots on failure.")])]),t._v(" "),e("li",[e("p",[e("code",[t._v("keepBrowserState")]),t._v(" - keep browser state between tests when "),e("code",[t._v("restart")]),t._v(" set to false.")])]),t._v(" "),e("li",[e("p",[e("code",[t._v("keepCookies")]),t._v(" - keep cookies between tests when "),e("code",[t._v("restart")]),t._v(" set to false.")])]),t._v(" "),e("li",[e("p",[e("code",[t._v("waitForAction")]),t._v(": (optional) how long to wait after click, doubleClick or PressKey actions in ms. Default: 500.")])]),t._v(" "),e("li",[e("p",[e("code",[t._v("waitForTimeout")]),t._v(": (optional) default wait* timeout in ms. Default: 1000.")])]),t._v(" "),e("li",[e("p",[e("code",[t._v("windowSize")]),t._v(": (optional) default window size. Set a dimension like "),e("code",[t._v("640x480")]),t._v(".")])]),t._v(" "),e("li",[e("p",[t._v("options from "),e("a",{attrs:{href:"https://github.com/segmentio/nightmare#api",target:"_blank",rel:"noopener noreferrer"}},[t._v("Nightmare configuration"),e("OutboundLink")],1)])])]),t._v(" "),e("h2",{attrs:{id:"methods"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#methods"}},[t._v("#")]),t._v(" Methods")]),t._v(" "),e("h3",{attrs:{id:"parameters"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("config")])])]),t._v(" "),e("h3",{attrs:{id:"locate"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#locate"}},[t._v("#")]),t._v(" _locate")]),t._v(" "),e("p",[t._v("Locate elements by different locator types, including strict locator.\nShould be used in custom helpers.")]),t._v(" "),e("p",[t._v("This method return promise with array of IDs of found elements.\nActual elements can be accessed inside "),e("code",[t._v("evaluate")]),t._v(" by using "),e("code",[t._v("codeceptjs.fetchElement()")]),t._v("\nclient-side function:")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// get an inner text of an element")]),t._v("\n\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" browser "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helpers"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Nightmare'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("browser"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("let")]),t._v(" value "),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v("=")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("this")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("helpers"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Nightmare'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("_locate")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),e("span",{pre:!0,attrs:{class:"token literal-property property"}},[t._v("name")]),e("span",{pre:!0,attrs:{class:"token operator"}},[t._v(":")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("then")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("els")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" browser"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("evaluate")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("function")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token parameter"}},[t._v("el")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("{")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token keyword"}},[t._v("return")]),t._v(" codeceptjs"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("fetchElement")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),t._v("el"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),t._v("value"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n "),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" els"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("[")]),e("span",{pre:!0,attrs:{class:"token number"}},[t._v("0")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("]")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("}")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-2"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-2"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")])])]),t._v(" "),e("h3",{attrs:{id:"amonpage"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#amonpage"}},[t._v("#")]),t._v(" amOnPage")]),t._v(" "),e("p",[t._v("Opens a web page in a browser. Requires relative or absolute url.\nIf url starts with "),e("code",[t._v("/")]),t._v(", opens a web page of a site defined in "),e("code",[t._v("url")]),t._v(" config parameter.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// opens main page of website")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'https://github.com'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// opens github")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("amOnPage")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'/login'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// opens a login page")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-3"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-3"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("url")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" url path or global url.")]),t._v(" "),e("li",[e("code",[t._v("headers")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v("?")]),t._v(" list of request headers can be passed")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")]),t._v(" "),e("h3",{attrs:{id:"appendfield"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#appendfield"}},[t._v("#")]),t._v(" appendField")]),t._v(" "),e("p",[t._v("Appends text to a input field or textarea.\nField is located by name, label, CSS or XPath")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("appendField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#myTextField'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'appended'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// typing secret")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("appendField")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'password'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("secret")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'123456'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-4"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-4"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("field")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" located by label|name|CSS|XPath|strict locator")]),t._v(" "),e("li",[e("code",[t._v("value")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" text value to append.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")]),t._v(" "),e("h3",{attrs:{id:"attachfile"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#attachfile"}},[t._v("#")]),t._v(" attachFile")]),t._v(" "),e("p",[t._v("Attaches a file to element located by label, name, CSS or XPath\nPath to file is relative current codecept directory (where codecept.conf.ts or codecept.conf.js is located).\nFile will be uploaded to remote system (if tests are running remotely).")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("attachFile")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'Avatar'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'data/avatar.jpg'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("attachFile")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'form input[name=avatar]'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'data/avatar.jpg'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-5"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-5"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("locator")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" field located by label|name|CSS|XPath|strict locator.")]),t._v(" "),e("li",[e("code",[t._v("pathToFile")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1)]),t._v(" local file path relative to codecept.conf.ts or codecept.conf.js config file.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorderDoesn't work if the Chromium DevTools panel is open (as Chromium allows only one attachment to the debugger at a time. "),e("a",{attrs:{href:"https://github.com/rosshinkley/nightmare-upload#important-note-about-setting-file-upload-inputs",target:"_blank",rel:"noopener noreferrer"}},[t._v("See more"),e("OutboundLink")],1),t._v(")")]),t._v(" "),e("h3",{attrs:{id:"checkoption"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#checkoption"}},[t._v("#")]),t._v(" checkOption")]),t._v(" "),e("p",[t._v("Selects a checkbox or radio button.\nElement is located by label or name or CSS or XPath.")]),t._v(" "),e("p",[t._v("The second parameter is a context (CSS or XPath locator) to narrow the search.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("checkOption")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'#agree'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("checkOption")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'I Agree to Terms and Conditions'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("checkOption")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'agree'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(",")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'//form'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-6"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-6"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("field")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v(" | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" checkbox located by label | name | CSS | XPath | strict locator.")]),t._v(" "),e("li",[e("code",[t._v("context")]),t._v(" "),e("strong",[t._v("("),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v("? | "),e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object",target:"_blank",rel:"noopener noreferrer"}},[t._v("object"),e("OutboundLink")],1),t._v(")")]),t._v(" (optional, "),e("code",[t._v("null")]),t._v(" by default) element located by CSS | XPath | strict locator.")])]),t._v(" "),e("p",[t._v("Returns "),e("strong",[t._v("void")]),t._v(" automatically synchronized promise through #recorder")]),t._v(" "),e("h3",{attrs:{id:"clearcookie"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#clearcookie"}},[t._v("#")]),t._v(" clearCookie")]),t._v(" "),e("p",[t._v("Clears a cookie by name,\nif none provided clears all cookies.")]),t._v(" "),e("div",{staticClass:"language-js extra-class"},[e("pre",{pre:!0,attrs:{class:"language-js"}},[e("code",[e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("clearCookie")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v("\n"),e("span",{pre:!0,attrs:{class:"token constant"}},[t._v("I")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(".")]),e("span",{pre:!0,attrs:{class:"token function"}},[t._v("clearCookie")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v("(")]),e("span",{pre:!0,attrs:{class:"token string"}},[t._v("'test'")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(")")]),e("span",{pre:!0,attrs:{class:"token punctuation"}},[t._v(";")]),t._v(" "),e("span",{pre:!0,attrs:{class:"token comment"}},[t._v("// Playwright currently doesn't support clear a particular cookie name")]),t._v("\n")])])]),e("h4",{attrs:{id:"parameters-7"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#parameters-7"}},[t._v("#")]),t._v(" Parameters")]),t._v(" "),e("ul",[e("li",[e("code",[t._v("cookie")]),t._v(" "),e("strong",[e("a",{attrs:{href:"https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String",target:"_blank",rel:"noopener noreferrer"}},[t._v("string"),e("OutboundLink")],1),t._v("?")]),t._v(" (optional, "),e("code",[t._v("null")]),t._v(" by default) cookie name")])]),t._v(" "),e("h3",{attrs:{id:"clearfield"}},[e("a",{staticClass:"header-anchor",attrs:{href:"#clearfield"}},[t._v("#")]),t._v(" clearField")]),t._v(" "),e("p",[t._v("Clears a "),e("code",[t._v("