Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

This file was deleted.

60 changes: 25 additions & 35 deletions docs/config/prepare-browser.mdx
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import Admonition from "@theme/Admonition";
import AddBrowserCommandExample from "@site/docs/config/_partials/examples/_prepare-browser-add-browser-command.mdx";
import AddElementCommandExample from "@site/docs/config/_partials/examples/_prepare-browser-add-element-command.mdx";
import OverwriteCommandExample from "@site/docs/config/_partials/examples/_prepare-browser-overwrite-command.mdx";
import AddMultipleCommandsExample from "@site/docs/config/_partials/examples/_prepare-browser-add-multiple-commands.mdx";

# prepareBrowser
Expand All @@ -10,44 +7,37 @@ import AddMultipleCommandsExample from "@site/docs/config/_partials/examples/_pr

This parameter is a hook. The function specified for this parameter will be automatically called before running tests in the browser. The function receives a reference to the browser session as an argument.

Typically, new commands are added to the browser or the behavior of existing commands is extended within this function.
The `prepareBrowser` hook is a perfect place to set up all of your custom commands or overwrite existing ones.

## Usage Examples {#example}

### Example 1: Adding a new command to the browser {#example_add_new_command_to_browser}

To add a new command, use the [browser.addCommand()][add-command] function.

<AddBrowserCommandExample />

### Example 2: Adding a new command to an element {#example_2_add_new_command_to_element}

You can add a command not to the browser, but to an element. In this case, the third argument of the [browser.addCommand()][add-command] function should be set to `true`.

<Admonition type="warning">
If a command is added to an element, not to the browser, the function is executed in the context
of the element!
<Admonition type="info">
Read more about custom commands in [our guide](../guides/custom-commands.mdx).
</Admonition>

<AddElementCommandExample />

Inside the function, the commands [getLocation()][get-location] and [getSize()][get-size], which are available for the element, are used.

After adding the `getCoords()` command, it can be used in tests as follows:
## Usage Examples {#example}

```typescript
const { left, top, right, bottom } = await browser.$(".selector").getCoords();
### Adding new browser commands or overwriting existing browser commands

This is how you can add or overwrite browser commands:

```typescript title="testplane.config.ts"
import type { ConfigInput } from "testplane";
import { openScenario, customUrl } from "./testplane/browser-commands";
import { getCoords } from "./testplane/element-commands";

export default {
// ...
prepareBrowser: function (browser) {
// Browser commands
browser.addCommand("openScenario", openScenario);
// Element commands
browser.addCommand("getCoords", getCoords, true);
// Browser command overwrites
browser.overwriteCommand("url", customUrl);
},
} satisfies ConfigInput;
```

### Example 3: Overwriting an existing command {#example_3_overwrite_command}

To change an existing command, use the [browser.overwriteCommand()][overwrite-command] command.

For example, we might want to pass an object with query parameters as a separate argument to the [browser.url()][url] command:

<OverwriteCommandExample />

### Example 4: Adding a set of commands from a folder {#example_4_add_commands_from_folder}
### Adding a set of commands from a folder

If the project has many specific commands, it is convenient to store them in a separate folder, and add all commands at once in a unified manner in `prepareBrowser`. For example:

Expand Down
116 changes: 116 additions & 0 deletions docs/guides/custom-commands.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";
import Admonition from "@theme/Admonition";
import AddElementCommandExample from "@site/docs/config/_partials/examples/_prepare-browser-add-element-command.mdx";

# Custom Commands

Testplane allows you to enhance your test suites by adding custom commands. These commands can streamline repetitive tasks, encapsulate complex actions, and improve code readability.

<Admonition title="What you'll learn">

- How to add custom commands to the browser object.
- How to add custom commands to elements.
- Ways to overwrite existing commands.
- Make custom commands work in a TypeScript environment.

</Admonition>

## Adding Custom Commands to the Browser Object

<Admonition type="tip">
A good place to add all of your custom commands is
[`prepareBrowser`](../config/prepare-browser.mdx) hook.
</Admonition>

To add a custom command to the `browser` object, use the `addCommand` method. Here's how you can define a command that retrieves both the URL and title of the current page:

```typescript
browser.addCommand("getUrlAndTitle", async function () {
// this in the context of custom commands points to browser object
return {
url: await this.getUrl(),
title: await this.getTitle(),
};
});
```

You can then use this custom command in your tests:

```typescript
it("should fetch URL and title", async function () {
const result = await browser.getUrlAndTitle();
console.log(result); // { url: 'https://example.com', title: 'Example Domain' }
});
```

## Adding Custom Commands to Elements

Custom commands can also be added to element instances. For instance, to create a command that gets element position:

<AddElementCommandExample />

Note the last, third parameter is set to `true` — it means that this command should be added to element instances.

## Overwriting Existing Commands

There might be scenarios where you need to modify the behavior of existing commands. Testplane allows you to overwrite these commands using the `overwriteCommand` method. For example, to add logging to the `click` command:

```typescript
browser.overwriteCommand("click", async function (this: WebdriverIO.Element, origClick, options) {
console.log("Element clicked:", this.selector);
await origClick(options);
});
```

In this example, before executing the original `click` function, a message is logged to the console.

## Using Custom Commands with TypeScript

To ensure TypeScript recognizes your custom commands, you need to augment the WebdriverIO types. To do that, follow these simple steps:

1. Create a `custom-commands.d.ts` file in your project.

2. Make sure TypeScript compiler "sees" this file during build: you might need to include it in your `tsconfig.json`.

3. Write your type definitions as follows. Note that there are two file contexts in TypeScript: module and ambient. If you have at least one import/export in your file, the file is in "module" mode, otherwise it's in ambient. Choose declaration style accordingly.

<Tabs>
<TabItem value="module" label="Module mode" default>

```typescript
import 'webdriverio'; // Can be any import, not necessarily webdriverio

declare global {
declare namespace WebdriverIO {
interface Browser {
customCommand: (arg: any) => Promise<void>
}

interface Element {
elementCustomCommand: (arg: any) => Promise<void>
}
}
}
```

</TabItem>
<TabItem value="ambient" label="Ambient mode">

```typescript
declare namespace WebdriverIO {
interface Browser {
customCommand: (arg: any) => Promise<void>
}

interface Element {
elementCustomCommand: (arg: any) => Promise<void>
}
}
```

</TabItem>

</Tabs>

This declaration extends the `Browser` and `Element` interfaces to include your custom commands, allowing TypeScript to recognize them without errors.
Original file line number Diff line number Diff line change
@@ -1,7 +1,4 @@
import Admonition from "@theme/Admonition";
import AddBrowserCommandExample from "@site/docs/config/_partials/examples/_prepare-browser-add-browser-command.mdx";
import AddElementCommandExample from "@site/docs/config/_partials/examples/_prepare-browser-add-element-command.mdx";
import OverwriteCommandExample from "@site/docs/config/_partials/examples/_prepare-browser-overwrite-command.mdx";
import AddMultipleCommandsExample from "@site/docs/config/_partials/examples/_prepare-browser-add-multiple-commands.mdx";

# prepareBrowser
Expand All @@ -12,42 +9,35 @@ import AddMultipleCommandsExample from "@site/docs/config/_partials/examples/_pr

Обычно внутри данной функции к браузеру добавляют новые команды, или расширяют поведение уже существующих команд.

## Примеры использования {#example}

### Пример 1: добавляем новую команду для браузера {#example_add_new_command_to_browser}

Для добавления новой команды воспользуемся функцией [browser.addCommand()][add-command].

<AddBrowserCommandExample />

### Пример 2: добавляем новую команду для элемента {#example_2_add_new_command_to_element}

Можно добавить команду не для браузера, а для элемента. Тогда третьим аргументом функции [browser.addCommand()][add-command] надо указать `true`.

<Admonition type="warning">
Если добавляется команда для элемента, а не для браузера, то функция выполняется в контексте
элемента!
<Admonition type="info">
Узнайте больше о кастомных командах в [нашем рецепте](../guides/custom-commands.mdx).
</Admonition>

<AddElementCommandExample />

Внутри функции применяются команды [getLocation()][get-location] и [getSize()][get-size], которые доступны для элемента.

После добавления команды `getCoords()`, её можно использовать в тестах следующим образом:
## Примеры использования {#example}

```typescript
const { left, top, right, bottom } = await browser.$(‘.selector’).getCoords();
### Добавление новых команд и перезапись существующих команд браузера

Так вы можете добавлять и перезаписывать браузерные команды:

```typescript title="testplane.config.ts"
import type { ConfigInput } from "testplane";
import { openScenario, customUrl } from "./testplane/browser-commands";
import { getCoords } from "./testplane/element-commands";

export default {
// ...
prepareBrowser: function (browser) {
// Browser commands
browser.addCommand("openScenario", openScenario);
// Element commands
browser.addCommand("getCoords", getCoords, true);
// Browser command overwrites
browser.overwriteCommand("url", customUrl);
},
} satisfies ConfigInput;
```

### Пример 3: меняем уже существующую команду {#example_3_overwrite_command}

Чтобы изменить уже существующую команду, воспользуемся командой [browser.overwriteCommand()][overwrite-command].

Например, мы можем захотеть передавать в команду [browser.url()][url] отдельным аргументом объект с query-параметрами:

<OverwriteCommandExample />

### Пример 4: добавляем набор команд из папки {#example_4_add_commands_from_folder}
### Добавление набора команд из папки

Если в проекте много своих специфических команд, то их удобно хранить в отдельной папке, а в `prepareBrowser` добавлять все команды сразу унифицированным образом. Например:

Expand Down
Loading