diff --git a/docs/advanced.md b/docs/advanced.md
index b1ff65939..b11f1d821 100644
--- a/docs/advanced.md
+++ b/docs/advanced.md
@@ -81,37 +81,6 @@ Data(function*() {
*HINT: If you don't use DataTable. add `toString()` method to each object added to data set, so the data could be pretty printed in a test name*
-## Tags
-
-Append `@tag` to your test name, so
-
-```js
-Scenario('update user profile @slow')
-```
-
-Alternativly, use `tag` method of Scenario to set additional tags:
-
-```js
-Scenario('update user profile', ({ }) => {
- // test goes here
-}).tag('@slow').tag('important');
-```
-
-All tests with `@tag` could be executed with `--grep '@tag'` option.
-
-```sh
-codeceptjs run --grep '@slow'
-```
-
-Use regex for more flexible filtering:
-
-* `--grep '(?=.*@smoke2)(?=.*@smoke3)'` - run tests with @smoke2 and @smoke3 in name
-* `--grep "\@smoke2|\@smoke3"` - run tests with @smoke2 or @smoke3 in name
-* `--grep '((?=.*@smoke2)(?=.*@smoke3))|@smoke4'` - run tests with (@smoke2 and @smoke3) or @smoke4 in name
-* `--grep '(?=.*@smoke2)^(?!.*@smoke3)'` - run tests with @smoke2 but without @smoke3 in name
-* `--grep '(?=.*)^(?!.*@smoke4)'` - run all tests except @smoke4
-
-
## Debug
@@ -185,167 +154,3 @@ You can use this options for build your own [plugins](https://codecept.io/hooks/
...
});
```
-
-## 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:
-
-```js
-// 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](/plugins/#steptimeout).
-
-### Tests Timeout
-
-Test timeout can be set in seconds via Scenario options:
-
-```js
-// 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:
-
-```js
-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.
-
-```js
-// limit all tests in this suite to 30 seconds
-Feature('flaky tests', { timeout: 30 })
-```
-
-### Timeout Confguration
-
-
-
-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:
-
-
-```js
-// 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:
-
-```js
-// 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:
-
-```js
-// 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`.
-
-```js
-Scenario('should be executed in firefox', ({ I }) => {
- // I.amOnPage(..)
-}).config({ browser: 'firefox' })
-```
-
-In this case `config` overrides current config of the first helper.
-To change config of specific helper pass two arguments: helper name and config values:
-
-```js
-Scenario('should create data via v2 version of API', ({ I }) => {
- // I.amOnPage(..)
-}).config('REST', { endpoint: 'https://api.mysite.com/v2' })
-```
-
-Config can also be set by a function, in this case you can get a test object and specify config values based on it.
-This is very useful when running tests against cloud providers, like BrowserStack. This function can also be asynchronous.
-
-```js
-Scenario('should report to BrowserStack', ({ I }) => {
- // I.amOnPage(..)
-}).config((test) => {
- return { desiredCapabilities: {
- project: test.suite.title,
- name: test.title,
- }}
-});
-```
-
-Config changes can be applied to all tests in suite:
-
-```js
-Feature('Admin Panel').config({ url: 'https://mysite.com/admin' });
-```
-
-Please note that some config changes can't be applied on the fly. For instance, if you set `restart: false` in your config and then changing value `browser` won't take an effect as browser is already started and won't be closed untill all tests finish.
-
-Configuration changes will be reverted after a test or a suite.
-
diff --git a/docs/basics.md b/docs/basics.md
index e7d11ca0a..d42febdff 100644
--- a/docs/basics.md
+++ b/docs/basics.md
@@ -16,996 +16,400 @@ Scenario('check Welcome page on site', ({ I }) => {
})
```
-Tests are expected to be written in **ECMAScript 7**.
+Tests are written as **ES modules** using modern JavaScript syntax.
Each test is described inside a `Scenario` function with the `I` object passed into it.
The `I` object is an **actor**, an abstraction for a testing user. The `I` is a proxy object for currently enabled **Helpers**.
-## Architecture
-
-CodeceptJS bypasses execution commands to helpers. Depending on the helper enabled, your tests will be executed differently.
-
-The following is a diagram of the CodeceptJS architecture:
-
-
-
-All helpers share the same API, so it's easy to migrate tests from one backend to another.
-However, because of the difference in backends and their limitations, they are not guaranteed to be compatible with each other. For instance, you can't set request headers in WebDriver but you can do so in Playwright or Puppeteer.
+## How It Works
-**Pick one helper, as it defines how tests are executed.** If requirements change it's easy to migrate to another.
+### Command Delegation to Helpers
----
+**CodeceptJS delegates all test commands to helper backends.** Tests written with the `I` object (the actor) don't directly execute actions. Instead, CodeceptJS routes them through configurable helpers:
-Refer to following guides to more information on:
+- **Playwright** - Chromium, Firefox, WebKit automation
+- **WebDriver** - Native browser automation via WebDriver Protocol
+- **Appium** - Mobile testing on iOS/Android
+- **Puppeteer** - Chromium automation via DevTools Protocol
-- [▶ Playwright](/playwright)
-- [▶ WebDriver](/webdriver)
-- [▶ Puppeteer](/puppeteer)
+All helpers share the same API, so it's easy to switch backends. However, due to backend differences and limitations, they aren't guaranteed to be compatible with each other. For example, you can set request headers in Playwright or Puppeteer, but not in WebDriver.
-> ℹ Depending on a helper selected a list of available actions may change.
+> **Pick one helper to define how your tests execute.** If requirements change, it's straightforward to migrate to another.
-To list all available commands for the current configuration run `codeceptjs list`
-or enable [auto-completion by generating TypeScript definitions](#intellisense).
-> 🤔 It is possible to access API of a backend you use inside a test or a [custom helper](/helpers/). For instance, to use Puppeteer API inside a test use [`I.usePuppeteerTo`](/helpers/Puppeteer/#usepuppeteerto) inside a test. Similar methods exist for each helper.
+### Promise Chain & Async/Await
-## Writing Tests
+Tests appear synchronous but **all actions are wrapped in promises and chained together** in a global promise chain. This means:
-Tests are written from a user's perspective. There is an actor (represented as `I`) which contains actions taken from helpers. A test is written as a sequence of actions performed by an actor:
+- **You usually don't need `await` for regular actions** - commands are automatically queued
+- Each `I.*` command is appended to the promise chain
+- Setup, teardown, and all test steps execute in sequence
```js
+// These execute in order WITHOUT await
I.amOnPage('/')
I.click('Login')
-I.see('Please Login', 'h1')
-// ...
-```
-
-### Opening a Page
-
-A test should usually start by navigating the browser to a website.
-
-Start a test by opening a page. Use the `I.amOnPage()` command for this:
-
-```js
-// When "http://site.com" is url in config
-I.amOnPage('/') // -> opens http://site.com/
-I.amOnPage('/about') // -> opens http://site.com/about
-I.amOnPage('https://google.com') // -> https://google.com
-```
-
-When an URL doesn't start with a protocol (http:// or https://) it is considered to be a relative URL and will be appended to the URL which was initially set-up in the config.
-
-> It is recommended to use a relative URL and keep the base URL in the config file, so you can easily switch between development, stage, and production environments.
-
-### Locating Element
-
-Element can be found by CSS or XPath locators.
-
-```js
-I.seeElement('.user') // element with CSS class user
-I.seeElement('//button[contains(., "press me")]') // button
-```
-
-By default CodeceptJS tries to guess the locator type.
-In order to specify the exact locator type you can pass an object called **strict locator**.
-
-```js
-I.seeElement({ css: 'div.user' })
-I.seeElement({ xpath: '//div[@class=user]' })
-```
-
-Strict locators allow to specify additional locator types:
-
-```js
-// locate form element by name
-I.seeElement({ name: 'password' })
-// locate element by React component and props
-I.seeElement({ react: 'user-profile', props: { name: 'davert' } })
-```
-
-In [mobile testing](https://codecept.io/mobile/#locating-elements) you can use `~` to specify the accessibility id to locate an element. In web application you can locate elements by their `aria-label` value.
-
-```js
-// locate element by [aria-label] attribute in web
-// or by accessibility id in mobile
-I.seeElement('~username')
-```
-
-> [▶ Learn more about using locators in CodeceptJS](/locators).
-
-### Clicking
-
-CodeceptJS provides a flexible syntax to specify an element to click.
-
-By default CodeceptJS tries to find the button or link with the exact text on it
-
-```js
-// search for link or button
-I.click('Login')
-```
-
-If none was found, CodeceptJS tries to find a link or button containing that text. In case an image is clickable its `alt` attribute will be checked for text inclusion. Form buttons will also be searched by name.
-
-To narrow down the results you can specify a context in the second parameter.
-
-```js
-I.click('Login', '.nav') // search only in .nav
-I.click('Login', { css: 'footer' }) // search only in footer
-```
-
-> To skip guessing the locator type, pass in a strict locator - A locator starting with '#' or '.' is considered to be CSS. Locators starting with '//' or './/' are considered to be XPath.
-
-You are not limited to buttons and links. Any element can be found by passing in valid CSS or XPath:
-
-```js
-// click element by CSS
-I.click('#signup')
-// click element located by special test-id attribute
-I.click('//dev[@test-id="myid"]')
-```
-
-> ℹ If click doesn't work in a test but works for user, it is possible that frontend application is not designed for automated testing. To overcome limitation of standard click in this edgecase use `forceClick` method. It will emulate click instead of sending native event. This command will click an element no matter if this element is visible or animating. It will send JavaScript "click" event to it.
-
-### Filling Fields
-
-Clicking the links is not what takes the most time during testing a web site. If your site consists only of links you can skip test automation. The most waste of time goes into the testing of forms. CodeceptJS provides several ways of doing that.
-
-Let's submit this sample form for a test:
-
-
-
-```html
-
-```
-
-We need to fill in all those fields and click the "Update" button. CodeceptJS matches form elements by their label, name, or by CSS or XPath locators.
-
-```js
-// we are using label to match user_name field
-I.fillField('Name', 'Miles')
-// we can use input name
-I.fillField('user[email]', 'miles@davis.com')
-// select element by label, choose option by text
-I.selectOption('Role', 'Admin')
-// click 'Save' button, found by text
-I.checkOption('Accept')
-I.click('Save')
-```
-
-> ℹ `selectOption` works only with standard `