testdriverai 7.2.47 → 7.2.49

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.
Files changed (56) hide show
  1. package/.github/workflows/acceptance-linux-scheduled.yaml +1 -1
  2. package/.github/workflows/acceptance.yaml +2 -2
  3. package/.github/workflows/windows-self-hosted.yaml +1 -1
  4. package/README.md +2 -2
  5. package/docs/TEST-GITHUB-COMMENTS.md +2 -2
  6. package/docs/v7/_drafts/plugin-migration.mdx +1 -1
  7. package/docs/v7/aws-setup.mdx +1 -1
  8. package/docs/v7/examples.mdx +1 -1
  9. package/{test/testdriver → examples}/ai.test.mjs +1 -1
  10. package/{test/testdriver → examples}/assert.test.mjs +1 -1
  11. package/{test/testdriver → examples}/chrome-extension.test.mjs +2 -2
  12. package/{test/testdriver → examples}/drag-and-drop.test.mjs +1 -1
  13. package/{test/testdriver → examples}/element-not-found.test.mjs +1 -1
  14. package/{test/testdriver → examples}/exec-output.test.mjs +1 -1
  15. package/{test/testdriver → examples}/exec-pwsh.test.mjs +1 -1
  16. package/{test/testdriver → examples}/focus-window.test.mjs +1 -1
  17. package/{test/testdriver → examples}/formatted-logging.test.mjs +1 -1
  18. package/{test/testdriver → examples}/hover-image.test.mjs +1 -1
  19. package/{test/testdriver → examples}/hover-text-with-description.test.mjs +1 -1
  20. package/{test/testdriver → examples}/hover-text.test.mjs +1 -1
  21. package/{test/testdriver → examples}/installer.test.mjs +1 -1
  22. package/{test/testdriver → examples}/launch-vscode-linux.test.mjs +1 -1
  23. package/{test/testdriver → examples}/match-image.test.mjs +1 -1
  24. package/{test/testdriver → examples}/press-keys.test.mjs +1 -1
  25. package/{test/testdriver → examples}/prompt.test.mjs +1 -1
  26. package/{test/testdriver → examples}/scroll-keyboard.test.mjs +1 -1
  27. package/{test/testdriver → examples}/scroll-until-image.test.mjs +1 -1
  28. package/{test/testdriver → examples}/scroll-until-text.test.mjs +1 -1
  29. package/{test/testdriver → examples}/scroll.test.mjs +1 -1
  30. package/{test/testdriver → examples}/type.test.mjs +1 -1
  31. package/{test/testdriver → examples}/windows-installer.test.mjs +1 -1
  32. package/package.json +1 -1
  33. package/test/manual/reconnect-provision.test.mjs +2 -2
  34. package/testdriver-plugin/skills/actions/SKILL.md +93 -0
  35. package/testdriver-plugin/skills/assertions/SKILL.md +77 -0
  36. package/testdriver-plugin/skills/caching/SKILL.md +66 -0
  37. package/testdriver-plugin/skills/creating-tests/SKILL.md +104 -0
  38. package/testdriver-plugin/skills/finding-elements/SKILL.md +77 -0
  39. package/testdriver-plugin/skills/github-actions/SKILL.md +100 -0
  40. package/testdriver-plugin/skills/running-tests/SKILL.md +77 -0
  41. package/testdriver-plugin/skills/secrets/SKILL.md +87 -0
  42. package/testdriver-plugin/skills/self-hosting/SKILL.md +89 -0
  43. package/testdriver-plugin/skills/setup/SKILL.md +76 -0
  44. package/testdriver-plugin/skills/variables/SKILL.md +88 -0
  45. package/testdriver-plugin/skills/waiting/SKILL.md +72 -0
  46. package/debug/01-table-initial.png +0 -0
  47. package/debug/02-after-ai-explore.png +0 -0
  48. package/debug/02-after-scroll.png +0 -0
  49. package/examples/github-actions.yml +0 -68
  50. package/examples/run-tests-with-recording.sh +0 -70
  51. package/examples/screenshot-example.js +0 -63
  52. package/examples/sdk-awesome-logs-demo.js +0 -177
  53. package/examples/sdk-cache-thresholds.js +0 -96
  54. package/examples/sdk-element-properties.js +0 -155
  55. package/examples/sdk-simple-example.js +0 -65
  56. package/examples/test-recording-example.test.js +0 -166
@@ -31,7 +31,7 @@ jobs:
31
31
 
32
32
  - name: Run Linux tests with Sentry Cron monitoring
33
33
  run: |
34
- sentry-cli monitors run testdriver-linux-acceptance -- npx vitest run test/testdriver/*.test.mjs
34
+ sentry-cli monitors run testdriver-linux-acceptance -- npx vitest run examples/*.test.mjs
35
35
  env:
36
36
  SENTRY_DSN: ${{ secrets.SENTRY_DSN }}
37
37
  TD_API_KEY: ${{ secrets.TD_API_KEY }}
@@ -29,7 +29,7 @@ jobs:
29
29
  run: npm ci
30
30
 
31
31
  - name: Run Linux tests
32
- run: npx vitest run test/testdriver/*.test.mjs
32
+ run: npx vitest run examples/*.test.mjs
33
33
  env:
34
34
  TD_API_KEY: ${{ secrets.TD_API_KEY }}
35
35
  TD_OS: linux
@@ -52,7 +52,7 @@ jobs:
52
52
  if: contains(github.event.pull_request.labels.*.name, 'test-windows')
53
53
  uses: ./.github/workflows/windows-self-hosted.yaml
54
54
  with:
55
- test_pattern: 'test/testdriver/assert.test.mjs'
55
+ test_pattern: 'examples/assert.test.mjs'
56
56
  secrets:
57
57
  TD_API_KEY: ${{ secrets.TD_API_KEY }}
58
58
  TD_WEBSITE: ${{ secrets.TD_WEBSITE }}
@@ -7,7 +7,7 @@ on:
7
7
  description: 'Test file pattern to run'
8
8
  required: false
9
9
  type: string
10
- default: 'test/testdriver/*.test.mjs'
10
+ default: 'examples/*.test.mjs'
11
11
  secrets:
12
12
  TD_API_KEY:
13
13
  required: true
package/README.md CHANGED
@@ -11,7 +11,7 @@
11
11
  <br />
12
12
  <br />
13
13
 
14
- [🚀 **Quick Start**](#-quick-start) • [📖 **Documentation**](https://docs.testdriver.ai) • [💻 **Examples**](https://github.com/testdriverai/testdriverai/tree/main/test/testdriver) • [📖 **Pricing**](https://docs.testdriver.ai) • [💬 **Discord**](https://discord.com/invite/cWDFW8DzPm) • [🌐 **Website**](https://testdriver.ai)
14
+ [🚀 **Quick Start**](#-quick-start) • [📖 **Documentation**](https://docs.testdriver.ai) • [💻 **Examples**](https://github.com/testdriverai/testdriverai/tree/main/examples) • [📖 **Pricing**](https://docs.testdriver.ai) • [💬 **Discord**](https://discord.com/invite/cWDFW8DzPm) • [🌐 **Website**](https://testdriver.ai)
15
15
 
16
16
  </div>
17
17
 
@@ -41,7 +41,7 @@ const result = await testdriver.assert(
41
41
  expect(result).toBeTruthy();
42
42
  ```
43
43
 
44
- [See Full Example](https://github.com/testdriverai/testdriverai/blob/main/test/testdriver/drag-and-drop.test.mjs) • [Browse All Examples](https://github.com/testdriverai/testdriverai/tree/main/test/testdriver)
44
+ [See Full Example](https://github.com/testdriverai/testdriverai/blob/main/examples/drag-and-drop.test.mjs) • [Browse All Examples](https://github.com/testdriverai/testdriverai/tree/main/examples)
45
45
 
46
46
  ---
47
47
 
@@ -38,7 +38,7 @@
38
38
 
39
39
  ## What the Test Does
40
40
 
41
- The workflow runs `test/testdriver/assert.test.mjs` which:
41
+ The workflow runs `examples/assert.test.mjs` which:
42
42
  - Provisions a Chrome browser
43
43
  - Navigates to https://saucedemo.com
44
44
  - Performs login actions
@@ -72,7 +72,7 @@ Skipped: 0 ⏭️
72
72
 
73
73
  | Status | Test | File | Duration | Replay |
74
74
  |--------|------|------|----------|--------|
75
- | ✅ | Assert Test | `test/testdriver/assert.test.mjs` | 25.3s | [🎥 View](https://console.testdriver.ai/replay/...) |
75
+ | ✅ | Assert Test | `examples/assert.test.mjs` | 25.3s | [🎥 View](https://console.testdriver.ai/replay/...) |
76
76
 
77
77
  ## 🎥 Dashcam Replays
78
78
 
@@ -142,7 +142,7 @@ export default defineConfig({
142
142
 
143
143
  ### Test Helpers
144
144
 
145
- - ✅ **Removed**: `test/testdriver/setup/` folder (legacy helpers)
145
+ - ✅ **Removed**: `examples/setup/` folder (legacy helpers)
146
146
  - Code moved to `lib/vitest/hooks.mjs` framework
147
147
  - Tests now use `TestDriver(context, options)` pattern directly
148
148
 
@@ -257,7 +257,7 @@ jobs:
257
257
  run: npm ci
258
258
 
259
259
  - name: Run Windows tests with self-hosted instances
260
- run: npx vitest run test/testdriver/*.test.mjs
260
+ run: npx vitest run examples/*.test.mjs
261
261
  env:
262
262
  TD_API_KEY: ${{ secrets.TD_API_KEY }}
263
263
  TD_OS: windows
@@ -1,5 +1,5 @@
1
1
  ---
2
2
  title: "Examples"
3
- url: "https://github.com/testdriverai/testdriverai/tree/main/test/testdriver"
3
+ url: "https://github.com/testdriverai/testdriverai/tree/main/examples"
4
4
  icon: 'code'
5
5
  ---
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
7
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
8
8
 
9
9
  describe("AI Test", () => {
10
10
  it("should use ai to search for testdriver on Google", async (context) => {
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
7
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
8
8
 
9
9
  describe("Assert Test", () => {
10
10
  it("should assert the testdriver login page shows", async (context) => {
@@ -8,7 +8,7 @@
8
8
  */
9
9
 
10
10
  import { describe, expect, it } from "vitest";
11
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
11
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
12
12
 
13
13
  describe("Chrome Extension Test", () => {
14
14
  it("should load hello-world Chrome extension from local path", async (context) => {
@@ -55,7 +55,7 @@ describe("Chrome Extension Test", () => {
55
55
  // When clicked, it shows a popup with "Hello Extensions"
56
56
 
57
57
  // Click on the extensions button (puzzle piece icon) in Chrome toolbar
58
- const extensionsButton = await testdriver.find("The extensions button in the Chrome toolbar");
58
+ const extensionsButton = await testdriver.find("The extensions button in the Chrome toolbar", {zoom: true});
59
59
  await extensionsButton.click();
60
60
 
61
61
  // Look for the hello world extension in the extensions menu
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
7
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
8
8
 
9
9
  const isLinux = (process.env.TD_OS || "linux") === "linux";
10
10
 
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
7
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
8
8
 
9
9
  describe("Element Not Found Test", () => {
10
10
  it("should handle non-existent element gracefully without timing out", async (context) => {
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
7
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
8
8
 
9
9
  describe.skip("Exec Output Test", () => {
10
10
  it(
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
7
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
8
8
 
9
9
  describe.skip("Exec PowerShell Test", () => {
10
10
  it(
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
7
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
8
8
 
9
9
  describe("Focus Window Test", () => {
10
10
  it.skip(
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
7
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
8
8
 
9
9
  describe("Formatted Logging Test", () => {
10
10
  it("should demonstrate formatted logs in dashcam replay", async (context) => {
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
7
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
8
8
 
9
9
  /**
10
10
  * Perform login flow for SauceLabs demo app
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
7
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
8
8
 
9
9
  /**
10
10
  * Perform login flow for SauceLabs demo app
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
7
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
8
8
 
9
9
  describe("Hover Text Test", () => {
10
10
  it("should click Sign In and verify error message", async (context) => {
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
7
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
8
8
 
9
9
  const isLinux = (process.env.TD_OS || "linux") === "linux";
10
10
 
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
2
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
3
3
 
4
4
  const isLinux = (process.env.TD_OS || "linux") === "linux";
5
5
 
@@ -6,7 +6,7 @@
6
6
  import path, { dirname } from "path";
7
7
  import { fileURLToPath } from "url";
8
8
  import { describe, expect, it } from "vitest";
9
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
9
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
10
10
 
11
11
  /**
12
12
  * Perform login flow for SauceLabs demo app
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
7
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
8
8
 
9
9
  describe("Press Keys Test", () => {
10
10
  it("should create tabs and navigate using keyboard shortcuts", async (context) => {
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
7
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
8
8
 
9
9
  describe.skip("Prompt Test", () => {
10
10
  it("should execute AI-driven prompts", async (context) => {
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
7
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
8
8
 
9
9
  describe("Scroll Keyboard Test", () => {
10
10
  it("should navigate to webhamster.com and scroll with keyboard", async (context) => {
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
7
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
8
8
 
9
9
  describe("Scroll Until Image Test", () => {
10
10
  it.skip("should scroll until brown colored house image appears", async (context) => {
@@ -4,7 +4,7 @@
4
4
  */
5
5
 
6
6
  import { describe, expect, it } from "vitest";
7
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
7
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
8
8
 
9
9
  /**
10
10
  * Perform login flow for SauceLabs demo app
@@ -6,7 +6,7 @@
6
6
  */
7
7
 
8
8
  import { describe, expect, it } from "vitest";
9
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
9
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
10
10
 
11
11
  describe("Scroll Test", () => {
12
12
  it("should navigate and scroll down the page", async (context) => {
@@ -1,5 +1,5 @@
1
1
  import { describe, expect, it } from "vitest";
2
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
2
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
3
3
 
4
4
  describe("Type Test", () => {
5
5
  it("should enter standard_user in username field", async (context) => {
@@ -10,7 +10,7 @@
10
10
  */
11
11
 
12
12
  import { describe, it } from "vitest";
13
- import { TestDriver } from "../../lib/vitest/hooks.mjs";
13
+ import { TestDriver } from "../lib/vitest/hooks.mjs";
14
14
 
15
15
  const isLinux = (process.env.TD_OS || "linux") === "linux";
16
16
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "testdriverai",
3
- "version": "7.2.47",
3
+ "version": "7.2.49",
4
4
  "description": "Next generation autonomous AI agent for end-to-end testing of web & desktop",
5
5
  "main": "sdk.js",
6
6
  "types": "sdk.d.ts",
@@ -8,8 +8,8 @@
8
8
  * Run reconnect-signin.test.mjs within 2 minutes of this test completing.
9
9
  *
10
10
  * Usage:
11
- * 1. npm test -- test/testdriver/reconnect-provision.test.mjs
12
- * 2. (within 2 minutes) npm test -- test/testdriver/reconnect-signin.test.mjs
11
+ * 1. npm test -- examples/reconnect-provision.test.mjs
12
+ * 2. (within 2 minutes) examples/reconnect-signin.test.mjs
13
13
  */
14
14
 
15
15
  import { afterAll, describe, expect, it } from "vitest";
@@ -0,0 +1,93 @@
1
+ ---
2
+ name: actions
3
+ description: Perform actions in TestDriver tests. Use when clicking, typing, pressing keys, scrolling, hovering, dragging, or interacting with UI elements.
4
+ ---
5
+
6
+ # Performing Actions
7
+
8
+ Read these docs:
9
+ - `node_modules/testdriverai/docs/v7/click.mdx`
10
+ - `node_modules/testdriverai/docs/v7/type.mdx`
11
+ - `node_modules/testdriverai/docs/v7/press-keys.mdx`
12
+ - `node_modules/testdriverai/docs/v7/scroll.mdx`
13
+ - `node_modules/testdriverai/docs/v7/hover.mdx`
14
+ - `node_modules/testdriverai/docs/v7/double-click.mdx`
15
+ - `node_modules/testdriverai/docs/v7/right-click.mdx`
16
+ - `node_modules/testdriverai/docs/v7/mouse-down.mdx`
17
+ - `node_modules/testdriverai/docs/v7/mouse-up.mdx`
18
+
19
+ ## Click Actions
20
+
21
+ ```javascript
22
+ const element = await testdriver.find("button");
23
+ await element.click();
24
+ await element.doubleClick();
25
+ await element.rightClick();
26
+ await element.hover();
27
+ ```
28
+
29
+ ## Typing
30
+
31
+ ```javascript
32
+ await testdriver.find("Email input").click();
33
+ await testdriver.type("user@example.com");
34
+ ```
35
+
36
+ ### Clear before typing
37
+ ```javascript
38
+ await testdriver.find("Search input").click();
39
+ await testdriver.pressKeys(["ctrl", "a"]);
40
+ await testdriver.type("new search term");
41
+ ```
42
+
43
+ ## Keyboard Input
44
+
45
+ ```javascript
46
+ await testdriver.pressKeys(["enter"]);
47
+ await testdriver.pressKeys(["tab"]);
48
+ await testdriver.pressKeys(["escape"]);
49
+ await testdriver.pressKeys(["ctrl", "a"]); // Select all
50
+ await testdriver.pressKeys(["ctrl", "c"]); // Copy
51
+ await testdriver.pressKeys(["ctrl", "v"]); // Paste
52
+ await testdriver.pressKeys(["alt", "f4"]); // Close (Windows)
53
+ await testdriver.pressKeys(["cmd", "q"]); // Quit (macOS)
54
+ ```
55
+
56
+ ## Scrolling
57
+
58
+ ```javascript
59
+ await testdriver.scroll("down");
60
+ await testdriver.scroll("up");
61
+ await testdriver.scrollUntilText("Footer content");
62
+ await testdriver.scrollUntilImage("Product image at bottom");
63
+ ```
64
+
65
+ ## Drag and Drop
66
+
67
+ ```javascript
68
+ const source = await testdriver.find("Draggable item");
69
+ const target = await testdriver.find("Drop zone");
70
+ await source.mouseDown();
71
+ await target.hover();
72
+ await target.mouseUp();
73
+ ```
74
+
75
+ ## Execute Code in Sandbox
76
+
77
+ ```javascript
78
+ // JavaScript (browser)
79
+ const title = await testdriver.exec("js", "return document.title", 5000);
80
+
81
+ // Shell (Linux)
82
+ await testdriver.exec("sh", "ls -la", 5000);
83
+
84
+ // PowerShell (Windows)
85
+ await testdriver.exec("pwsh", "Get-Date", 5000);
86
+ ```
87
+
88
+ ## Examples
89
+
90
+ - `node_modules/testdriverai/examples/type.test.mjs`
91
+ - `node_modules/testdriverai/examples/press-keys.test.mjs`
92
+ - `node_modules/testdriverai/examples/scroll.test.mjs`
93
+ - `node_modules/testdriverai/examples/drag-and-drop.test.mjs`
@@ -0,0 +1,77 @@
1
+ ---
2
+ name: assertions
3
+ description: Make assertions in TestDriver tests. Use when verifying UI state, checking visual conditions, or validating test outcomes with natural language.
4
+ ---
5
+
6
+ # Making Assertions
7
+
8
+ Read: `node_modules/testdriverai/docs/v7/assert.mdx`
9
+ Read: `node_modules/testdriverai/docs/v7/making-assertions.mdx`
10
+
11
+ ## Basic Usage
12
+
13
+ ```javascript
14
+ const result = await testdriver.assert("the dashboard is visible");
15
+ expect(result).toBeTruthy();
16
+ ```
17
+
18
+ ## Writing Good Assertions
19
+
20
+ **Be specific:**
21
+ ```javascript
22
+ // ✅ Good
23
+ await testdriver.assert("the login button is visible in the header");
24
+ await testdriver.assert("user's name 'John' appears in the profile section");
25
+ await testdriver.assert("error message 'Invalid email' is displayed");
26
+
27
+ // ❌ Vague
28
+ await testdriver.assert("button visible");
29
+ await testdriver.assert("it worked");
30
+ ```
31
+
32
+ **Describe what you see:**
33
+ ```javascript
34
+ await testdriver.assert("the settings panel is open on the right side");
35
+ await testdriver.assert("a green success checkmark appears next to the form");
36
+ await testdriver.assert("the page shows 'Welcome back, John'");
37
+ ```
38
+
39
+ **Include context:**
40
+ ```javascript
41
+ await testdriver.assert("the shopping cart shows 3 items");
42
+ await testdriver.assert("the price total is $99.99");
43
+ await testdriver.assert("the submit button is disabled");
44
+ ```
45
+
46
+ ## Common Patterns
47
+
48
+ ### After navigation
49
+ ```javascript
50
+ await testdriver.find("Settings link").click();
51
+ const result = await testdriver.assert("Settings page is displayed");
52
+ expect(result).toBeTruthy();
53
+ ```
54
+
55
+ ### Form validation
56
+ ```javascript
57
+ await testdriver.find("Submit button").click();
58
+ const hasError = await testdriver.assert("email validation error is shown");
59
+ expect(hasError).toBeTruthy();
60
+ ```
61
+
62
+ ### State changes
63
+ ```javascript
64
+ await testdriver.find("Toggle switch").click();
65
+ const isOn = await testdriver.assert("the toggle is now in the ON position");
66
+ expect(isOn).toBeTruthy();
67
+ ```
68
+
69
+ ### Negative assertions
70
+ ```javascript
71
+ const noError = await testdriver.assert("no error messages are visible");
72
+ expect(noError).toBeTruthy();
73
+ ```
74
+
75
+ ## Examples
76
+
77
+ See `node_modules/testdriverai/examples/assert.test.mjs`
@@ -0,0 +1,66 @@
1
+ ---
2
+ name: caching
3
+ description: Understand TestDriver element caching. Use when optimizing test speed, managing cache keys, or troubleshooting cached element issues.
4
+ ---
5
+
6
+ # Element Caching
7
+
8
+ Read: `node_modules/testdriverai/docs/v7/caching.mdx`
9
+
10
+ ## How Caching Works
11
+
12
+ TestDriver caches element locations to speed up subsequent test runs. When you `find()` an element, the result is stored and reused in future runs.
13
+
14
+ ## Cache Options
15
+
16
+ ```javascript
17
+ const testdriver = TestDriver(context, {
18
+ cache: true, // Enable caching (default: true)
19
+ cacheKey: 'my-test', // Custom cache key
20
+ });
21
+ ```
22
+
23
+ ## When to Use Custom Cache Keys
24
+
25
+ Use different cache keys when:
26
+ - Testing different pages/states with similar elements
27
+ - Running tests in different environments
28
+ - Elements have different positions in different contexts
29
+
30
+ ```javascript
31
+ // Login page test
32
+ const testdriver = TestDriver(context, { cacheKey: 'login-page' });
33
+
34
+ // Dashboard test
35
+ const testdriver = TestDriver(context, { cacheKey: 'dashboard' });
36
+ ```
37
+
38
+ ## Disabling Cache
39
+
40
+ Disable caching when:
41
+ - Elements frequently change position
42
+ - Debugging element detection issues
43
+ - Dynamic content that varies between runs
44
+
45
+ ```javascript
46
+ const testdriver = TestDriver(context, { cache: false });
47
+ ```
48
+
49
+ ## Cache Invalidation
50
+
51
+ The cache is automatically invalidated when:
52
+ - Element is not found at cached location
53
+ - Test fails due to element mismatch
54
+ - Cache key changes
55
+
56
+ ## Troubleshooting
57
+
58
+ **Element found at wrong position?**
59
+ - Try disabling cache: `cache: false`
60
+ - Use a different cache key
61
+ - The UI may have changed since last run
62
+
63
+ **Tests slower than expected?**
64
+ - Ensure caching is enabled
65
+ - Use consistent cache keys
66
+ - Cache builds up over successful runs