testdriverai 6.2.2 → 7.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/acceptance-linux.yml +75 -0
- package/.github/workflows/acceptance-sdk-tests.yml +133 -0
- package/.vscode/settings.json +5 -1
- package/AGENTS.md +550 -0
- package/CODEOWNERS +0 -1
- package/README.md +126 -0
- package/{testdriver → _testdriver}/acceptance/drag-and-drop.yaml +2 -2
- package/{testdriver → _testdriver}/acceptance/snippets/login.yaml +1 -1
- package/_testdriver/examples/desktop/lifecycle/prerun.yaml +0 -0
- package/{testdriver → _testdriver}/examples/web/lifecycle/prerun.yaml +6 -1
- package/{testdriver → _testdriver}/lifecycle/postrun.yaml +3 -2
- package/_testdriver/lifecycle/prerun.yaml +15 -0
- package/{testdriver → _testdriver}/lifecycle/provision.yaml +7 -2
- package/agent/index.js +300 -85
- package/agent/interface.js +15 -0
- package/agent/lib/cache.js +142 -0
- package/agent/lib/commander.js +1 -39
- package/agent/lib/commands.js +910 -296
- package/agent/lib/redraw.js +129 -41
- package/agent/lib/sandbox.js +29 -6
- package/agent/lib/sdk.js +22 -0
- package/agent/lib/system.js +0 -3
- package/agent/lib/validation.js +1 -7
- package/debug-locate-response.js +82 -0
- package/debugger/index.html +15 -4
- package/docs/ARCHITECTURE.md +424 -0
- package/docs/AWESOME_LOGS_QUICK_REF.md +100 -0
- package/docs/MIGRATION.md +425 -0
- package/docs/PRESETS.md +210 -0
- package/docs/QUICK_START_TEST_RECORDING.md +215 -0
- package/docs/SDK_AWESOME_LOGS.md +468 -0
- package/docs/TEST_RECORDING.md +388 -0
- package/docs/docs.json +286 -152
- package/docs/guide/best-practices-polling.mdx +154 -0
- package/docs/sdk-browser-rendering.md +167 -0
- package/docs/v6/getting-started/self-hosting.mdx +407 -0
- package/docs/{guide → v6/guide}/dashcam.mdx +1 -1
- package/docs/{guide → v6/guide}/environment-variables.mdx +4 -5
- package/docs/{guide → v6/guide}/lifecycle.mdx +1 -1
- package/docs/v6/overview/comparison.mdx +101 -0
- package/docs/v7/README.md +135 -0
- package/docs/v7/api/ai.mdx +205 -0
- package/docs/v7/api/assert.mdx +285 -0
- package/docs/v7/api/assertions.mdx +403 -0
- package/docs/v7/api/click.mdx +287 -0
- package/docs/v7/api/client.mdx +322 -0
- package/docs/v7/api/dashcam.mdx +497 -0
- package/docs/v7/api/doubleClick.mdx +102 -0
- package/docs/v7/api/elements.mdx +479 -0
- package/docs/v7/api/exec.mdx +346 -0
- package/docs/v7/api/find.mdx +316 -0
- package/docs/v7/api/focusApplication.mdx +294 -0
- package/docs/v7/api/hover.mdx +279 -0
- package/docs/v7/api/mouseDown.mdx +161 -0
- package/docs/v7/api/mouseUp.mdx +164 -0
- package/docs/v7/api/pressKeys.mdx +349 -0
- package/docs/v7/api/rightClick.mdx +123 -0
- package/docs/v7/api/sandbox.mdx +404 -0
- package/docs/v7/api/scroll.mdx +300 -0
- package/docs/v7/api/type.mdx +314 -0
- package/docs/v7/commands/assert.mdx +45 -0
- package/docs/v7/commands/exec.mdx +282 -0
- package/docs/v7/commands/focus-application.mdx +44 -0
- package/docs/v7/commands/hover-image.mdx +69 -0
- package/docs/v7/commands/hover-text.mdx +47 -0
- package/docs/v7/commands/if.mdx +53 -0
- package/docs/v7/commands/match-image.mdx +67 -0
- package/docs/v7/commands/press-keys.mdx +87 -0
- package/docs/v7/commands/remember.mdx +49 -0
- package/docs/v7/commands/run.mdx +44 -0
- package/docs/v7/commands/scroll-until-image.mdx +66 -0
- package/docs/v7/commands/scroll-until-text.mdx +60 -0
- package/docs/v7/commands/scroll.mdx +69 -0
- package/docs/v7/commands/type.mdx +45 -0
- package/docs/v7/commands/wait-for-image.mdx +54 -0
- package/docs/v7/commands/wait-for-text.mdx +48 -0
- package/docs/v7/commands/wait.mdx +45 -0
- package/docs/v7/getting-started/configuration.mdx +380 -0
- package/docs/v7/getting-started/quickstart.mdx +332 -0
- package/docs/v7/guides/best-practices.mdx +486 -0
- package/docs/v7/guides/caching-ai.mdx +215 -0
- package/docs/v7/guides/caching-selectors.mdx +292 -0
- package/docs/v7/guides/caching.mdx +366 -0
- package/docs/v7/guides/ci-cd/azure.mdx +587 -0
- package/docs/v7/guides/ci-cd/circleci.mdx +523 -0
- package/docs/v7/guides/ci-cd/github-actions.mdx +457 -0
- package/docs/v7/guides/ci-cd/gitlab.mdx +498 -0
- package/docs/v7/guides/ci-cd/jenkins.mdx +664 -0
- package/docs/v7/guides/ci-cd/travis.mdx +438 -0
- package/docs/v7/guides/debugging.mdx +349 -0
- package/docs/v7/guides/faq.mdx +393 -0
- package/docs/v7/guides/migration.mdx +562 -0
- package/docs/v7/guides/performance.mdx +517 -0
- package/docs/{getting-started → v7/guides}/self-hosting.mdx +11 -12
- package/docs/v7/guides/troubleshooting.mdx +526 -0
- package/docs/v7/guides/vitest-plugin.mdx +477 -0
- package/docs/v7/guides/vitest.mdx +535 -0
- package/docs/v7/platforms/linux.mdx +308 -0
- package/docs/v7/platforms/macos.mdx +433 -0
- package/docs/v7/platforms/windows.mdx +430 -0
- package/docs/v7/playwright.mdx +342 -0
- package/docs/v7/presets/chrome-extension.mdx +223 -0
- package/docs/v7/presets/chrome.mdx +287 -0
- package/docs/v7/presets/electron.mdx +435 -0
- package/docs/v7/presets/vscode.mdx +398 -0
- package/docs/v7/presets/webapp.mdx +396 -0
- package/docs/v7/progressive-apis/CORE.md +459 -0
- package/docs/v7/progressive-apis/HOOKS.md +360 -0
- package/docs/v7/progressive-apis/PROGRESSIVE_DISCLOSURE.md +230 -0
- package/docs/v7/progressive-apis/PROVISION.md +266 -0
- package/eslint.config.js +19 -1
- package/interfaces/cli/lib/base.js +10 -4
- package/interfaces/logger.js +2 -1
- package/interfaces/shared-test-state.mjs +69 -0
- package/interfaces/vitest-plugin.mjs +830 -0
- package/package.json +29 -5
- package/schema.json +8 -29
- package/scripts/view-test-results.mjs +96 -0
- package/sdk-log-formatter.js +714 -0
- package/sdk.d.ts +1028 -0
- package/sdk.js +2567 -0
- package/{.github/workflows/self-hosted.yml → self-hosted.yml} +13 -4
- package/setup/aws/cloudformation.yaml +9 -2
- package/src/core/Dashcam.js +469 -0
- package/src/core/index.d.ts +150 -0
- package/src/core/index.js +12 -0
- package/src/presets/index.mjs +331 -0
- package/src/vitest/extended.mjs +108 -0
- package/src/vitest/hooks.d.ts +119 -0
- package/src/vitest/hooks.mjs +298 -0
- package/src/vitest/index.mjs +64 -0
- package/src/vitest/lifecycle.mjs +277 -0
- package/src/vitest/utils.mjs +150 -0
- package/test/dashcam.test.js +137 -0
- package/test/mcp-example-test.yaml +27 -0
- package/testdriver/acceptance-sdk/QUICK_REFERENCE.md +61 -0
- package/testdriver/acceptance-sdk/README.md +128 -0
- package/testdriver/acceptance-sdk/TEST_REPORTING.md +245 -0
- package/testdriver/acceptance-sdk/assert.test.mjs +26 -0
- package/testdriver/acceptance-sdk/auto-cache-key-demo.test.mjs +56 -0
- package/testdriver/acceptance-sdk/chrome-extension.test.mjs +89 -0
- package/testdriver/acceptance-sdk/drag-and-drop.test.mjs +58 -0
- package/testdriver/acceptance-sdk/element-not-found.test.mjs +25 -0
- package/testdriver/acceptance-sdk/exec-js.test.mjs +43 -0
- package/testdriver/acceptance-sdk/exec-output.test.mjs +59 -0
- package/testdriver/acceptance-sdk/exec-pwsh.test.mjs +57 -0
- package/testdriver/acceptance-sdk/focus-window.test.mjs +36 -0
- package/testdriver/acceptance-sdk/formatted-logging.test.mjs +26 -0
- package/testdriver/acceptance-sdk/hooks-example.test.mjs +38 -0
- package/testdriver/acceptance-sdk/hover-image.test.mjs +34 -0
- package/testdriver/acceptance-sdk/hover-text-with-description.test.mjs +38 -0
- package/testdriver/acceptance-sdk/hover-text.test.mjs +27 -0
- package/testdriver/acceptance-sdk/match-image.test.mjs +36 -0
- package/testdriver/acceptance-sdk/presets-example.test.mjs +87 -0
- package/testdriver/acceptance-sdk/press-keys.test.mjs +50 -0
- package/testdriver/acceptance-sdk/prompt.test.mjs +33 -0
- package/testdriver/acceptance-sdk/scroll-keyboard.test.mjs +38 -0
- package/testdriver/acceptance-sdk/scroll-until-image.test.mjs +39 -0
- package/testdriver/acceptance-sdk/scroll-until-text.test.mjs +28 -0
- package/testdriver/acceptance-sdk/scroll.test.mjs +41 -0
- package/testdriver/acceptance-sdk/setup/globalTeardown.mjs +11 -0
- package/testdriver/acceptance-sdk/setup/testHelpers.mjs +420 -0
- package/testdriver/acceptance-sdk/setup/vitestSetup.mjs +40 -0
- package/testdriver/acceptance-sdk/sully-ai.test.mjs +234 -0
- package/testdriver/acceptance-sdk/test-console-logs.test.mjs +42 -0
- package/testdriver/acceptance-sdk/type-checking-demo.js +49 -0
- package/testdriver/acceptance-sdk/type.test.mjs +45 -0
- package/verify-element-api.js +89 -0
- package/verify-types.js +0 -0
- package/vitest.config.example.js +19 -0
- package/vitest.config.mjs +66 -0
- package/vitest.config.mjs.bak +44 -0
- package/.github/workflows/acceptance-v6.yml +0 -169
- package/.vscode/mcp.json +0 -9
- package/docs/overview/comparison.mdx +0 -82
- package/testdriver/lifecycle/prerun.yaml +0 -17
- /package/{testdriver/examples/desktop/lifecycle/prerun.yaml → .env.example} +0 -0
- /package/{testdriver → _testdriver}/acceptance/assert.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/dashcam.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/embed.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/exec-js.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/exec-output.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/exec-shell.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/focus-window.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/hover-image.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/hover-text-with-description.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/hover-text.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/if-else.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/match-image.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/press-keys.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/prompt.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/remember.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/screenshots/cart.png +0 -0
- /package/{testdriver → _testdriver}/acceptance/scroll-keyboard.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/scroll-until-image.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/scroll-until-text.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/scroll.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/snippets/match-cart.yaml +0 -0
- /package/{testdriver → _testdriver}/acceptance/type.yaml +0 -0
- /package/{testdriver → _testdriver}/behavior/failure.yaml +0 -0
- /package/{testdriver → _testdriver}/behavior/hover-text.yaml +0 -0
- /package/{testdriver → _testdriver}/behavior/lifecycle/postrun.yaml +0 -0
- /package/{testdriver → _testdriver}/behavior/lifecycle/prerun.yaml +0 -0
- /package/{testdriver → _testdriver}/behavior/lifecycle/provision.yaml +0 -0
- /package/{testdriver → _testdriver}/behavior/secrets.yaml +0 -0
- /package/{testdriver → _testdriver}/edge-cases/dashcam-chrome.yaml +0 -0
- /package/{testdriver → _testdriver}/edge-cases/exec-pwsh-multiline.yaml +0 -0
- /package/{testdriver → _testdriver}/edge-cases/js-exception.yaml +0 -0
- /package/{testdriver → _testdriver}/edge-cases/js-promise.yaml +0 -0
- /package/{testdriver → _testdriver}/edge-cases/lifecycle/postrun.yaml +0 -0
- /package/{testdriver → _testdriver}/edge-cases/prompt-in-middle.yaml +0 -0
- /package/{testdriver → _testdriver}/edge-cases/prompt-nested.yaml +0 -0
- /package/{testdriver → _testdriver}/edge-cases/success-test.yaml +0 -0
- /package/{testdriver → _testdriver}/examples/android/example.yaml +0 -0
- /package/{testdriver → _testdriver}/examples/android/lifecycle/postrun.yaml +0 -0
- /package/{testdriver → _testdriver}/examples/android/lifecycle/provision.yaml +0 -0
- /package/{testdriver → _testdriver}/examples/android/readme.md +0 -0
- /package/{testdriver → _testdriver}/examples/chrome-extension/lifecycle/provision.yaml +0 -0
- /package/{testdriver → _testdriver}/examples/desktop/lifecycle/provision.yaml +0 -0
- /package/{testdriver → _testdriver}/examples/vscode-extension/lifecycle/provision.yaml +0 -0
- /package/{testdriver → _testdriver}/examples/web/lifecycle/postrun.yaml +0 -0
- /package/docs/{account → v6/account}/dashboard.mdx +0 -0
- /package/docs/{account → v6/account}/enterprise.mdx +0 -0
- /package/docs/{account → v6/account}/pricing.mdx +0 -0
- /package/docs/{account → v6/account}/projects.mdx +0 -0
- /package/docs/{account → v6/account}/team.mdx +0 -0
- /package/docs/{action → v6/action}/ami.mdx +0 -0
- /package/docs/{action → v6/action}/performance.mdx +0 -0
- /package/docs/{action → v6/action}/secrets.mdx +0 -0
- /package/docs/{apps → v6/apps}/chrome-extensions.mdx +0 -0
- /package/docs/{apps → v6/apps}/desktop-apps.mdx +0 -0
- /package/docs/{apps → v6/apps}/mobile-apps.mdx +0 -0
- /package/docs/{apps → v6/apps}/static-websites.mdx +0 -0
- /package/docs/{apps → v6/apps}/tauri-apps.mdx +0 -0
- /package/docs/{bugs → v6/bugs}/jira.mdx +0 -0
- /package/docs/{cli → v6/cli}/overview.mdx +0 -0
- /package/docs/{commands → v6/commands}/assert.mdx +0 -0
- /package/docs/{commands → v6/commands}/exec.mdx +0 -0
- /package/docs/{commands → v6/commands}/focus-application.mdx +0 -0
- /package/docs/{commands → v6/commands}/hover-image.mdx +0 -0
- /package/docs/{commands → v6/commands}/hover-text.mdx +0 -0
- /package/docs/{commands → v6/commands}/if.mdx +0 -0
- /package/docs/{commands → v6/commands}/match-image.mdx +0 -0
- /package/docs/{commands → v6/commands}/press-keys.mdx +0 -0
- /package/docs/{commands → v6/commands}/remember.mdx +0 -0
- /package/docs/{commands → v6/commands}/run.mdx +0 -0
- /package/docs/{commands → v6/commands}/scroll-until-image.mdx +0 -0
- /package/docs/{commands → v6/commands}/scroll-until-text.mdx +0 -0
- /package/docs/{commands → v6/commands}/scroll.mdx +0 -0
- /package/docs/{commands → v6/commands}/type.mdx +0 -0
- /package/docs/{commands → v6/commands}/wait-for-image.mdx +0 -0
- /package/docs/{commands → v6/commands}/wait-for-text.mdx +0 -0
- /package/docs/{commands → v6/commands}/wait.mdx +0 -0
- /package/docs/{exporting → v6/exporting}/junit.mdx +0 -0
- /package/docs/{exporting → v6/exporting}/playwright.mdx +0 -0
- /package/docs/{features → v6/features}/auto-healing.mdx +0 -0
- /package/docs/{features → v6/features}/generation.mdx +0 -0
- /package/docs/{features → v6/features}/parallel-testing.mdx +0 -0
- /package/docs/{features → v6/features}/reusable-snippets.mdx +0 -0
- /package/docs/{features → v6/features}/selectorless.mdx +0 -0
- /package/docs/{features → v6/features}/visual-assertions.mdx +0 -0
- /package/docs/{getting-started → v6/getting-started}/ci.mdx +0 -0
- /package/docs/{getting-started → v6/getting-started}/cli.mdx +0 -0
- /package/docs/{getting-started → v6/getting-started}/editing.mdx +0 -0
- /package/docs/{getting-started → v6/getting-started}/playwright.mdx +0 -0
- /package/docs/{getting-started → v6/getting-started}/running.mdx +0 -0
- /package/docs/{getting-started → v6/getting-started}/vscode.mdx +0 -0
- /package/docs/{guide → v6/guide}/assertions.mdx +0 -0
- /package/docs/{guide → v6/guide}/authentication.mdx +0 -0
- /package/docs/{guide → v6/guide}/code.mdx +0 -0
- /package/docs/{guide → v6/guide}/locating.mdx +0 -0
- /package/docs/{guide → v6/guide}/protips.mdx +0 -0
- /package/docs/{guide → v6/guide}/variables.mdx +0 -0
- /package/docs/{guide → v6/guide}/waiting.mdx +0 -0
- /package/docs/{importing → v6/importing}/csv.mdx +0 -0
- /package/docs/{importing → v6/importing}/gherkin.mdx +0 -0
- /package/docs/{importing → v6/importing}/jira.mdx +0 -0
- /package/docs/{importing → v6/importing}/testrail.mdx +0 -0
- /package/docs/{integrations → v6/integrations}/electron.mdx +0 -0
- /package/docs/{integrations → v6/integrations}/netlify.mdx +0 -0
- /package/docs/{integrations → v6/integrations}/vercel.mdx +0 -0
- /package/docs/{interactive → v6/interactive}/explore.mdx +0 -0
- /package/docs/{interactive → v6/interactive}/run.mdx +0 -0
- /package/docs/{interactive → v6/interactive}/save.mdx +0 -0
- /package/docs/{overview → v6/overview}/faq.mdx +0 -0
- /package/docs/{overview → v6/overview}/performance.mdx +0 -0
- /package/docs/{overview → v6/overview}/quickstart.mdx +0 -0
- /package/docs/{overview → v6/overview}/what-is-testdriver.mdx +0 -0
- /package/docs/{scenarios → v6/scenarios}/ai-chatbot.mdx +0 -0
- /package/docs/{scenarios → v6/scenarios}/cookie-banner.mdx +0 -0
- /package/docs/{scenarios → v6/scenarios}/file-upload.mdx +0 -0
- /package/docs/{scenarios → v6/scenarios}/form-filling.mdx +0 -0
- /package/docs/{scenarios → v6/scenarios}/log-in.mdx +0 -0
- /package/docs/{scenarios → v6/scenarios}/pdf-generation.mdx +0 -0
- /package/docs/{scenarios → v6/scenarios}/spell-check.mdx +0 -0
- /package/docs/{security → v6/security}/action.mdx +0 -0
- /package/docs/{security → v6/security}/agent.mdx +0 -0
- /package/docs/{security → v6/security}/platform.mdx +0 -0
- /package/docs/{tutorials → v6/tutorials}/advanced-test.mdx +0 -0
- /package/docs/{tutorials → v6/tutorials}/basic-test.mdx +0 -0
|
@@ -0,0 +1,300 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "scroll()"
|
|
3
|
+
sidebarTitle: "scroll"
|
|
4
|
+
description: "Scroll pages and elements"
|
|
5
|
+
icon: "arrows-up-down"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Scroll the page or active element in any direction using mouse wheel or keyboard.
|
|
11
|
+
|
|
12
|
+
## Syntax
|
|
13
|
+
|
|
14
|
+
```javascript
|
|
15
|
+
await testdriver.scroll(direction, amount, method)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Parameters
|
|
19
|
+
|
|
20
|
+
<ParamField path="direction" type="string" default="down">
|
|
21
|
+
Direction to scroll: `'up'`, `'down'`, `'left'`, `'right'`
|
|
22
|
+
</ParamField>
|
|
23
|
+
|
|
24
|
+
<ParamField path="amount" type="number" default="300">
|
|
25
|
+
Amount to scroll in pixels
|
|
26
|
+
</ParamField>
|
|
27
|
+
|
|
28
|
+
<ParamField path="method" type="string" default="mouse">
|
|
29
|
+
Scroll method: `'mouse'` or `'keyboard'`
|
|
30
|
+
</ParamField>
|
|
31
|
+
|
|
32
|
+
## Returns
|
|
33
|
+
|
|
34
|
+
`Promise<void>`
|
|
35
|
+
|
|
36
|
+
## Examples
|
|
37
|
+
|
|
38
|
+
### Basic Scrolling
|
|
39
|
+
|
|
40
|
+
```javascript
|
|
41
|
+
// Scroll down (default)
|
|
42
|
+
await testdriver.scroll();
|
|
43
|
+
|
|
44
|
+
// Scroll down 500 pixels
|
|
45
|
+
await testdriver.scroll('down', 500);
|
|
46
|
+
|
|
47
|
+
// Scroll up
|
|
48
|
+
await testdriver.scroll('up');
|
|
49
|
+
|
|
50
|
+
// Scroll up 200 pixels
|
|
51
|
+
await testdriver.scroll('up', 200);
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### Horizontal Scrolling
|
|
55
|
+
|
|
56
|
+
```javascript
|
|
57
|
+
// Scroll right
|
|
58
|
+
await testdriver.scroll('right', 300);
|
|
59
|
+
|
|
60
|
+
// Scroll left
|
|
61
|
+
await testdriver.scroll('left', 300);
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Scroll Methods
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
// Mouse wheel scroll (smooth, pixel-precise)
|
|
68
|
+
await testdriver.scroll('down', 300, 'mouse');
|
|
69
|
+
|
|
70
|
+
// Keyboard scroll (uses Page Down/Up, more compatible)
|
|
71
|
+
await testdriver.scroll('down', 300, 'keyboard');
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Scroll Until Found
|
|
75
|
+
|
|
76
|
+
### scrollUntilText()
|
|
77
|
+
|
|
78
|
+
Scroll until specific text appears on screen.
|
|
79
|
+
|
|
80
|
+
```javascript
|
|
81
|
+
await testdriver.scrollUntilText(text, direction, maxDistance, textMatchMethod, method, invert)
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
**Parameters:**
|
|
85
|
+
- `text` (string) - Text to find
|
|
86
|
+
- `direction` (string) - Scroll direction (default: `'down'`)
|
|
87
|
+
- `maxDistance` (number) - Max pixels to scroll (default: 10000)
|
|
88
|
+
- `textMatchMethod` (string) - `'turbo'` or `'ai'` (default: `'turbo'`)
|
|
89
|
+
- `method` (string) - `'keyboard'` or `'mouse'` (default: `'keyboard'`)
|
|
90
|
+
- `invert` (boolean) - Scroll until text disappears (default: false)
|
|
91
|
+
|
|
92
|
+
**Examples:**
|
|
93
|
+
```javascript
|
|
94
|
+
// Scroll down until "Contact Us" appears
|
|
95
|
+
await testdriver.scrollUntilText('Contact Us');
|
|
96
|
+
|
|
97
|
+
// Scroll up to find text
|
|
98
|
+
await testdriver.scrollUntilText('Header', 'up');
|
|
99
|
+
|
|
100
|
+
// Scroll until text disappears
|
|
101
|
+
await testdriver.scrollUntilText('Loading...', 'down', 5000, 'turbo', 'keyboard', true);
|
|
102
|
+
|
|
103
|
+
// Use AI matching for fuzzy text
|
|
104
|
+
await testdriver.scrollUntilText('footer content', 'down', 10000, 'ai');
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
### scrollUntilImage()
|
|
108
|
+
|
|
109
|
+
Scroll until a visual element appears.
|
|
110
|
+
|
|
111
|
+
```javascript
|
|
112
|
+
await testdriver.scrollUntilImage(description, direction, maxDistance, method, path, invert)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
**Parameters:**
|
|
116
|
+
- `description` (string) - Description of the image/element
|
|
117
|
+
- `direction` (string) - Scroll direction (default: `'down'`)
|
|
118
|
+
- `maxDistance` (number) - Max pixels to scroll (default: 10000)
|
|
119
|
+
- `method` (string) - `'keyboard'` or `'mouse'` (default: `'keyboard'`)
|
|
120
|
+
- `path` (string | null) - Path to image template (optional)
|
|
121
|
+
- `invert` (boolean) - Scroll until image disappears (default: false)
|
|
122
|
+
|
|
123
|
+
**Examples:**
|
|
124
|
+
```javascript
|
|
125
|
+
// Scroll until visual element appears
|
|
126
|
+
await testdriver.scrollUntilImage('red subscribe button');
|
|
127
|
+
|
|
128
|
+
// Scroll using image template
|
|
129
|
+
await testdriver.scrollUntilImage('', 'down', 10000, 'keyboard', './footer-logo.png');
|
|
130
|
+
|
|
131
|
+
// Scroll until image disappears
|
|
132
|
+
await testdriver.scrollUntilImage('loading spinner', 'down', 5000, 'keyboard', null, true);
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## Best Practices
|
|
136
|
+
|
|
137
|
+
<Check>
|
|
138
|
+
**Choose the right scroll method**
|
|
139
|
+
|
|
140
|
+
```javascript
|
|
141
|
+
// For web pages, mouse scroll is usually smoother
|
|
142
|
+
await testdriver.scroll('down', 300, 'mouse');
|
|
143
|
+
|
|
144
|
+
// For desktop apps or when mouse doesn't work
|
|
145
|
+
await testdriver.scroll('down', 300, 'keyboard');
|
|
146
|
+
```
|
|
147
|
+
</Check>
|
|
148
|
+
|
|
149
|
+
<Check>
|
|
150
|
+
**Use scrollUntil for dynamic content**
|
|
151
|
+
|
|
152
|
+
```javascript
|
|
153
|
+
// Instead of guessing scroll amount
|
|
154
|
+
await testdriver.scrollUntilText('Load More button');
|
|
155
|
+
|
|
156
|
+
const loadMoreBtn = await testdriver.find('Load More button');
|
|
157
|
+
await loadMoreBtn.click();
|
|
158
|
+
```
|
|
159
|
+
</Check>
|
|
160
|
+
|
|
161
|
+
<Check>
|
|
162
|
+
**Set reasonable max distance**
|
|
163
|
+
|
|
164
|
+
```javascript
|
|
165
|
+
// Avoid infinite scrolling
|
|
166
|
+
await testdriver.scrollUntilText('Footer', 'down', 5000); // Max 5000px
|
|
167
|
+
```
|
|
168
|
+
</Check>
|
|
169
|
+
|
|
170
|
+
<Warning>
|
|
171
|
+
**Keyboard scroll uses Page Down/Up**
|
|
172
|
+
|
|
173
|
+
Keyboard scrolling typically moves by one "page" at a time, which may be more than the specified pixel amount. It's more compatible but less precise than mouse scrolling.
|
|
174
|
+
</Warning>
|
|
175
|
+
|
|
176
|
+
## Use Cases
|
|
177
|
+
|
|
178
|
+
<AccordionGroup>
|
|
179
|
+
<Accordion title="Navigate to Footer">
|
|
180
|
+
```javascript
|
|
181
|
+
// Scroll to bottom of page
|
|
182
|
+
await testdriver.scrollUntilText('Contact Us');
|
|
183
|
+
|
|
184
|
+
const contactLink = await testdriver.find('Contact Us link');
|
|
185
|
+
await contactLink.click();
|
|
186
|
+
```
|
|
187
|
+
</Accordion>
|
|
188
|
+
|
|
189
|
+
<Accordion title="Load More Results">
|
|
190
|
+
```javascript
|
|
191
|
+
// Scroll to load more button
|
|
192
|
+
await testdriver.scrollUntilText('Load More');
|
|
193
|
+
|
|
194
|
+
const loadBtn = await testdriver.find('Load More button');
|
|
195
|
+
await loadBtn.click();
|
|
196
|
+
|
|
197
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
198
|
+
```
|
|
199
|
+
</Accordion>
|
|
200
|
+
|
|
201
|
+
<Accordion title="Find Element in Long List">
|
|
202
|
+
```javascript
|
|
203
|
+
// Scroll through list to find item
|
|
204
|
+
await testdriver.scrollUntilText('Product #42');
|
|
205
|
+
|
|
206
|
+
const product = await testdriver.find('Product #42');
|
|
207
|
+
await product.click();
|
|
208
|
+
```
|
|
209
|
+
</Accordion>
|
|
210
|
+
|
|
211
|
+
<Accordion title="Infinite Scroll">
|
|
212
|
+
```javascript
|
|
213
|
+
// Scroll multiple times for infinite scroll
|
|
214
|
+
for (let i = 0; i < 5; i++) {
|
|
215
|
+
await testdriver.scroll('down', 500);
|
|
216
|
+
await new Promise(r => setTimeout(r, 1000)); // Wait for load
|
|
217
|
+
}
|
|
218
|
+
```
|
|
219
|
+
</Accordion>
|
|
220
|
+
|
|
221
|
+
<Accordion title="Horizontal Gallery">
|
|
222
|
+
```javascript
|
|
223
|
+
// Navigate horizontal carousel
|
|
224
|
+
await testdriver.scroll('right', 300);
|
|
225
|
+
await new Promise(r => setTimeout(r, 500));
|
|
226
|
+
|
|
227
|
+
const nextImage = await testdriver.find('next image in carousel');
|
|
228
|
+
await nextImage.click();
|
|
229
|
+
```
|
|
230
|
+
</Accordion>
|
|
231
|
+
</AccordionGroup>
|
|
232
|
+
|
|
233
|
+
## Complete Example
|
|
234
|
+
|
|
235
|
+
```javascript
|
|
236
|
+
import { beforeAll, afterAll, describe, it } from 'vitest';
|
|
237
|
+
import TestDriver from 'testdriverai';
|
|
238
|
+
|
|
239
|
+
describe('Scrolling', () => {
|
|
240
|
+
let testdriver;
|
|
241
|
+
|
|
242
|
+
beforeAll(async () => {
|
|
243
|
+
client = new TestDriver(process.env.TD_API_KEY);
|
|
244
|
+
await testdriver.auth();
|
|
245
|
+
await testdriver.connect({ newSandbox: true });
|
|
246
|
+
});
|
|
247
|
+
|
|
248
|
+
afterAll(async () => {
|
|
249
|
+
await testdriver.disconnect();
|
|
250
|
+
});
|
|
251
|
+
|
|
252
|
+
it('should scroll to find elements', async () => {
|
|
253
|
+
await testdriver.focusApplication('Google Chrome');
|
|
254
|
+
|
|
255
|
+
// Scroll to footer
|
|
256
|
+
await testdriver.scrollUntilText('Contact Information');
|
|
257
|
+
|
|
258
|
+
// Click footer link
|
|
259
|
+
const privacyLink = await testdriver.find('Privacy Policy link');
|
|
260
|
+
await privacyLink.click();
|
|
261
|
+
|
|
262
|
+
await testdriver.assert('privacy policy page is displayed');
|
|
263
|
+
});
|
|
264
|
+
|
|
265
|
+
it('should handle infinite scroll', async () => {
|
|
266
|
+
await testdriver.focusApplication('Google Chrome');
|
|
267
|
+
|
|
268
|
+
// Scroll multiple times to load content
|
|
269
|
+
for (let i = 0; i < 3; i++) {
|
|
270
|
+
await testdriver.scroll('down', 500);
|
|
271
|
+
await new Promise(r => setTimeout(r, 1500)); // Wait for load
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// Verify content loaded
|
|
275
|
+
await testdriver.assert('more than 10 items are visible');
|
|
276
|
+
});
|
|
277
|
+
|
|
278
|
+
it('should scroll until loading completes', async () => {
|
|
279
|
+
// Scroll until loading spinner disappears
|
|
280
|
+
await testdriver.scrollUntilImage(
|
|
281
|
+
'loading spinner',
|
|
282
|
+
'down',
|
|
283
|
+
5000,
|
|
284
|
+
'keyboard',
|
|
285
|
+
null,
|
|
286
|
+
true // invert - wait for it to disappear
|
|
287
|
+
);
|
|
288
|
+
|
|
289
|
+
// Now interact with loaded content
|
|
290
|
+
const firstResult = await testdriver.find('first search result');
|
|
291
|
+
await firstResult.click();
|
|
292
|
+
});
|
|
293
|
+
});
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
## Related Methods
|
|
297
|
+
|
|
298
|
+
- [`find()`](/v7/api/find) - Locate elements after scrolling
|
|
299
|
+
- [`pressKeys()`](/v7/api/pressKeys) - Use Page Down/Up keys
|
|
300
|
+
- [`wait()`](/v7/api/wait) - Wait after scrolling
|
|
@@ -0,0 +1,314 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "type()"
|
|
3
|
+
sidebarTitle: "type"
|
|
4
|
+
description: "Type text into focused input fields"
|
|
5
|
+
icon: "keyboard"
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Overview
|
|
9
|
+
|
|
10
|
+
Type text or numbers into the currently focused input field with optional delay between keystrokes.
|
|
11
|
+
|
|
12
|
+
## Syntax
|
|
13
|
+
|
|
14
|
+
```javascript
|
|
15
|
+
await testdriver.type(text, delay)
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
## Parameters
|
|
19
|
+
|
|
20
|
+
<ParamField path="text" type="string | number" required>
|
|
21
|
+
Text to type (can be a string or number)
|
|
22
|
+
</ParamField>
|
|
23
|
+
|
|
24
|
+
<ParamField path="delay" type="number" default="250">
|
|
25
|
+
Delay between keystrokes in milliseconds
|
|
26
|
+
</ParamField>
|
|
27
|
+
|
|
28
|
+
## Returns
|
|
29
|
+
|
|
30
|
+
`Promise<void>`
|
|
31
|
+
|
|
32
|
+
## Examples
|
|
33
|
+
|
|
34
|
+
### Basic Typing
|
|
35
|
+
|
|
36
|
+
```javascript
|
|
37
|
+
// Type text
|
|
38
|
+
await testdriver.type('hello@example.com');
|
|
39
|
+
|
|
40
|
+
// Type numbers
|
|
41
|
+
await testdriver.type(12345);
|
|
42
|
+
|
|
43
|
+
// Type with custom delay
|
|
44
|
+
await testdriver.type('slow typing', 500); // 500ms between each character
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### Form Filling
|
|
48
|
+
|
|
49
|
+
```javascript
|
|
50
|
+
// Focus field and type
|
|
51
|
+
const emailField = await testdriver.find('email input');
|
|
52
|
+
await emailField.click();
|
|
53
|
+
await testdriver.type('user@example.com');
|
|
54
|
+
|
|
55
|
+
// Tab to next field and type
|
|
56
|
+
await testdriver.pressKeys(['tab']);
|
|
57
|
+
await testdriver.type('John Doe');
|
|
58
|
+
|
|
59
|
+
// Type password
|
|
60
|
+
await testdriver.pressKeys(['tab']);
|
|
61
|
+
await testdriver.type('MySecureP@ssw0rd');
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
### Clearing and Replacing Text
|
|
65
|
+
|
|
66
|
+
```javascript
|
|
67
|
+
const searchBox = await testdriver.find('search input');
|
|
68
|
+
await searchBox.click();
|
|
69
|
+
|
|
70
|
+
// Clear existing text
|
|
71
|
+
await testdriver.pressKeys(['ctrl', 'a']); // Select all
|
|
72
|
+
await testdriver.type('new search query');
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Best Practices
|
|
76
|
+
|
|
77
|
+
<Check>
|
|
78
|
+
**Focus the field first**
|
|
79
|
+
|
|
80
|
+
Always click the input field or navigate to it before typing:
|
|
81
|
+
|
|
82
|
+
```javascript
|
|
83
|
+
const input = await testdriver.find('username input');
|
|
84
|
+
await input.click();
|
|
85
|
+
await testdriver.type('testuser');
|
|
86
|
+
```
|
|
87
|
+
</Check>
|
|
88
|
+
|
|
89
|
+
<Check>
|
|
90
|
+
**Use Tab for navigation**
|
|
91
|
+
|
|
92
|
+
Navigate between fields using Tab instead of clicking each one:
|
|
93
|
+
|
|
94
|
+
```javascript
|
|
95
|
+
const firstField = await testdriver.find('first name');
|
|
96
|
+
await firstField.click();
|
|
97
|
+
await testdriver.type('John');
|
|
98
|
+
|
|
99
|
+
await testdriver.pressKeys(['tab']);
|
|
100
|
+
await testdriver.type('Doe');
|
|
101
|
+
|
|
102
|
+
await testdriver.pressKeys(['tab']);
|
|
103
|
+
await testdriver.type('john@example.com');
|
|
104
|
+
```
|
|
105
|
+
</Check>
|
|
106
|
+
|
|
107
|
+
<Check>
|
|
108
|
+
**Clear fields before typing**
|
|
109
|
+
|
|
110
|
+
Clear existing content to avoid appending:
|
|
111
|
+
|
|
112
|
+
```javascript
|
|
113
|
+
const input = await testdriver.find('search field');
|
|
114
|
+
await input.click();
|
|
115
|
+
await testdriver.pressKeys(['ctrl', 'a']); // Select all
|
|
116
|
+
await testdriver.type('new search');
|
|
117
|
+
```
|
|
118
|
+
</Check>
|
|
119
|
+
|
|
120
|
+
<Warning>
|
|
121
|
+
**Field must be focused**
|
|
122
|
+
|
|
123
|
+
Typing will only work if an input field is currently focused. If no field is focused, the text may be lost or trigger unexpected keyboard shortcuts.
|
|
124
|
+
</Warning>
|
|
125
|
+
|
|
126
|
+
## Use Cases
|
|
127
|
+
|
|
128
|
+
<AccordionGroup>
|
|
129
|
+
<Accordion title="Login Forms">
|
|
130
|
+
```javascript
|
|
131
|
+
await testdriver.focusApplication('Google Chrome');
|
|
132
|
+
|
|
133
|
+
const usernameField = await testdriver.find('username input');
|
|
134
|
+
await usernameField.click();
|
|
135
|
+
await testdriver.type('testuser@example.com');
|
|
136
|
+
|
|
137
|
+
await testdriver.pressKeys(['tab']);
|
|
138
|
+
await testdriver.type('MyP@ssword123');
|
|
139
|
+
|
|
140
|
+
await testdriver.pressKeys(['enter']);
|
|
141
|
+
```
|
|
142
|
+
</Accordion>
|
|
143
|
+
|
|
144
|
+
<Accordion title="Search Fields">
|
|
145
|
+
```javascript
|
|
146
|
+
const searchBox = await testdriver.find('search input');
|
|
147
|
+
await searchBox.click();
|
|
148
|
+
await testdriver.type('laptop computers');
|
|
149
|
+
await testdriver.pressKeys(['enter']);
|
|
150
|
+
|
|
151
|
+
// Wait for results
|
|
152
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
153
|
+
```
|
|
154
|
+
</Accordion>
|
|
155
|
+
|
|
156
|
+
<Accordion title="Multi-Field Forms">
|
|
157
|
+
```javascript
|
|
158
|
+
// First field
|
|
159
|
+
const nameField = await testdriver.find('full name input');
|
|
160
|
+
await nameField.click();
|
|
161
|
+
await testdriver.type('Jane Smith');
|
|
162
|
+
|
|
163
|
+
// Navigate with Tab
|
|
164
|
+
await testdriver.pressKeys(['tab']);
|
|
165
|
+
await testdriver.type('jane.smith@example.com');
|
|
166
|
+
|
|
167
|
+
await testdriver.pressKeys(['tab']);
|
|
168
|
+
await testdriver.type('+1-555-0123');
|
|
169
|
+
|
|
170
|
+
await testdriver.pressKeys(['tab']);
|
|
171
|
+
await testdriver.type('123 Main Street');
|
|
172
|
+
```
|
|
173
|
+
</Accordion>
|
|
174
|
+
|
|
175
|
+
<Accordion title="Text Editors">
|
|
176
|
+
```javascript
|
|
177
|
+
const editor = await testdriver.find('text editor area');
|
|
178
|
+
await editor.click();
|
|
179
|
+
|
|
180
|
+
await testdriver.type('# My Document', 100);
|
|
181
|
+
await testdriver.pressKeys(['enter', 'enter']);
|
|
182
|
+
await testdriver.type('This is the first paragraph.', 50);
|
|
183
|
+
```
|
|
184
|
+
</Accordion>
|
|
185
|
+
|
|
186
|
+
<Accordion title="Numeric Input">
|
|
187
|
+
```javascript
|
|
188
|
+
const quantityField = await testdriver.find('quantity input');
|
|
189
|
+
await quantityField.click();
|
|
190
|
+
|
|
191
|
+
// Clear field
|
|
192
|
+
await testdriver.pressKeys(['ctrl', 'a']);
|
|
193
|
+
|
|
194
|
+
// Type number
|
|
195
|
+
await testdriver.type(5);
|
|
196
|
+
```
|
|
197
|
+
</Accordion>
|
|
198
|
+
</AccordionGroup>
|
|
199
|
+
|
|
200
|
+
## Typing Speed
|
|
201
|
+
|
|
202
|
+
Adjust the delay parameter based on your needs:
|
|
203
|
+
|
|
204
|
+
```javascript
|
|
205
|
+
// Fast typing (100ms delay)
|
|
206
|
+
await testdriver.type('quick entry', 100);
|
|
207
|
+
|
|
208
|
+
// Normal typing (250ms - default)
|
|
209
|
+
await testdriver.type('standard speed');
|
|
210
|
+
|
|
211
|
+
// Slow typing (500ms delay) - useful for fields with live validation
|
|
212
|
+
await testdriver.type('slow and steady', 500);
|
|
213
|
+
|
|
214
|
+
// Very slow (1000ms delay) - for problematic fields
|
|
215
|
+
await testdriver.type('one by one', 1000);
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
<Note>
|
|
219
|
+
Some applications with live validation or autocomplete may require slower typing speeds to avoid race conditions.
|
|
220
|
+
</Note>
|
|
221
|
+
|
|
222
|
+
## Special Characters
|
|
223
|
+
|
|
224
|
+
```javascript
|
|
225
|
+
// Email addresses
|
|
226
|
+
await testdriver.type('user@example.com');
|
|
227
|
+
|
|
228
|
+
// URLs
|
|
229
|
+
await testdriver.type('https://example.com/path?query=value');
|
|
230
|
+
|
|
231
|
+
// Passwords with special characters
|
|
232
|
+
await testdriver.type('P@ssw0rd!#$%');
|
|
233
|
+
|
|
234
|
+
// Paths
|
|
235
|
+
await testdriver.type('C:\\Users\\Documents\\file.txt');
|
|
236
|
+
|
|
237
|
+
// Multi-line text (use pressKeys for Enter)
|
|
238
|
+
await testdriver.type('Line 1');
|
|
239
|
+
await testdriver.pressKeys(['enter']);
|
|
240
|
+
await testdriver.type('Line 2');
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
## Complete Example
|
|
244
|
+
|
|
245
|
+
```javascript
|
|
246
|
+
import { beforeAll, afterAll, describe, it, expect } from 'vitest';
|
|
247
|
+
import TestDriver from 'testdriverai';
|
|
248
|
+
|
|
249
|
+
describe('Form Filling with Type', () => {
|
|
250
|
+
let testdriver;
|
|
251
|
+
|
|
252
|
+
beforeAll(async () => {
|
|
253
|
+
client = new TestDriver(process.env.TD_API_KEY);
|
|
254
|
+
await testdriver.auth();
|
|
255
|
+
await testdriver.connect({ newSandbox: true });
|
|
256
|
+
});
|
|
257
|
+
|
|
258
|
+
afterAll(async () => {
|
|
259
|
+
await testdriver.disconnect();
|
|
260
|
+
});
|
|
261
|
+
|
|
262
|
+
it('should fill out registration form', async () => {
|
|
263
|
+
await testdriver.focusApplication('Google Chrome');
|
|
264
|
+
|
|
265
|
+
// Email field
|
|
266
|
+
const emailField = await testdriver.find('email input field');
|
|
267
|
+
await emailField.click();
|
|
268
|
+
await testdriver.type('john.doe@example.com');
|
|
269
|
+
|
|
270
|
+
// Tab through form fields
|
|
271
|
+
await testdriver.pressKeys(['tab']);
|
|
272
|
+
await testdriver.type('John');
|
|
273
|
+
|
|
274
|
+
await testdriver.pressKeys(['tab']);
|
|
275
|
+
await testdriver.type('Doe');
|
|
276
|
+
|
|
277
|
+
await testdriver.pressKeys(['tab']);
|
|
278
|
+
await testdriver.type('MySecureP@ssword123');
|
|
279
|
+
|
|
280
|
+
await testdriver.pressKeys(['tab']);
|
|
281
|
+
await testdriver.type('MySecureP@ssword123'); // Confirm password
|
|
282
|
+
|
|
283
|
+
// Verify fields were filled
|
|
284
|
+
const result = await testdriver.assert('all form fields are filled');
|
|
285
|
+
expect(result).toBeTruthy();
|
|
286
|
+
});
|
|
287
|
+
|
|
288
|
+
it('should update search query', async () => {
|
|
289
|
+
const searchBox = await testdriver.find('search input');
|
|
290
|
+
await searchBox.click();
|
|
291
|
+
|
|
292
|
+
// Type initial search
|
|
293
|
+
await testdriver.type('laptops');
|
|
294
|
+
await testdriver.pressKeys(['enter']);
|
|
295
|
+
|
|
296
|
+
await new Promise(r => setTimeout(r, 2000));
|
|
297
|
+
|
|
298
|
+
// Update search
|
|
299
|
+
await searchBox.click();
|
|
300
|
+
await testdriver.pressKeys(['ctrl', 'a']); // Select all
|
|
301
|
+
await testdriver.type('gaming laptops');
|
|
302
|
+
await testdriver.pressKeys(['enter']);
|
|
303
|
+
|
|
304
|
+
// Verify new search
|
|
305
|
+
await testdriver.assert('search results for "gaming laptops" are shown');
|
|
306
|
+
});
|
|
307
|
+
});
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
## Related Methods
|
|
311
|
+
|
|
312
|
+
- [`pressKeys()`](/v7/api/pressKeys) - Press keyboard keys and shortcuts
|
|
313
|
+
- [`find()`](/v7/api/find) - Locate input fields
|
|
314
|
+
- [`click()`](/v7/api/click) - Focus input fields
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: "assert"
|
|
3
|
+
sidebarTitle: "assert"
|
|
4
|
+
description: "Validate conditions during a test using the assert command."
|
|
5
|
+
icon: "check"
|
|
6
|
+
mode: "wide"
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
import Replay from "/snippets/tests/assert-replay.mdx";
|
|
10
|
+
import Example from "/snippets/tests/assert-yaml.mdx";
|
|
11
|
+
|
|
12
|
+
<Replay />
|
|
13
|
+
<Example />
|
|
14
|
+
|
|
15
|
+
## Description
|
|
16
|
+
|
|
17
|
+
The `assert` command validates that a specific condition is true. It ensures that a task completed successfully by checking the screen for the expected outcome. If the condition isn't met, the test will fail.
|
|
18
|
+
|
|
19
|
+
## Arguments
|
|
20
|
+
|
|
21
|
+
| Argument | Type | Description |
|
|
22
|
+
| -------- | --------- | ------------------------------------------------------------------------------------------------------------------ |
|
|
23
|
+
| `expect` | `string` | The condition to check. This should describe what you expect to see on the screen. |
|
|
24
|
+
| `async` | `boolean` | (Optional) If set to `true`, the test will continue without waiting for the assertion to pass. Default is `false`. |
|
|
25
|
+
| `invert` | `boolean` | (Optional) If set to `true`, will fail if the assertion passes. |
|
|
26
|
+
|
|
27
|
+
## Example usage
|
|
28
|
+
|
|
29
|
+
```yaml
|
|
30
|
+
command: assert
|
|
31
|
+
expect: the video is playing
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
### Example with `async`
|
|
35
|
+
|
|
36
|
+
```yaml
|
|
37
|
+
command: assert
|
|
38
|
+
expect: There is no error message
|
|
39
|
+
async: true
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Notes
|
|
43
|
+
|
|
44
|
+
- Use `async: true` to speed up tests by allowing non-blocking assertions. However, the test will still fail if the condition isn't met.
|
|
45
|
+
- Ensure the `expect` string clearly describes the condition to avoid ambiguity.
|