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,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Formatted Logging Demo
|
|
3
|
+
* Demonstrates nice Vitest-style formatted logs for Dashcam replay
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
8
|
+
|
|
9
|
+
describe("Formatted Logging Test", () => {
|
|
10
|
+
it("should demonstrate formatted logs in dashcam replay", async (context) => {
|
|
11
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
12
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
13
|
+
|
|
14
|
+
// Find and click - logs will be nicely formatted
|
|
15
|
+
const signInButton = await testdriver.find(
|
|
16
|
+
"Sign In, black button below the password field",
|
|
17
|
+
);
|
|
18
|
+
await signInButton.click();
|
|
19
|
+
|
|
20
|
+
// Assert - logs will show pass/fail with nice formatting
|
|
21
|
+
const result = await testdriver.assert(
|
|
22
|
+
"an error shows that fields are required",
|
|
23
|
+
);
|
|
24
|
+
expect(result).toBeTruthy();
|
|
25
|
+
});
|
|
26
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver Hooks API Demo
|
|
3
|
+
* Demonstrates the new React-style hooks for Vitest
|
|
4
|
+
*
|
|
5
|
+
* This is the SIMPLEST way to use TestDriver with Vitest!
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, expect, it } from "vitest";
|
|
9
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
10
|
+
|
|
11
|
+
describe("Hooks API Demo", () => {
|
|
12
|
+
it("should use hooks for automatic lifecycle management", async (context) => {
|
|
13
|
+
// ✨ One line gets you TestDriver + Dashcam with full auto-lifecycle!
|
|
14
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
15
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
16
|
+
|
|
17
|
+
// Everything is automatic:
|
|
18
|
+
// - Sandbox connection ✅
|
|
19
|
+
// - Dashcam recording ✅
|
|
20
|
+
// - Chrome launch ✅
|
|
21
|
+
// - Recording stop ✅
|
|
22
|
+
// - Cleanup ✅
|
|
23
|
+
|
|
24
|
+
await testdriver.focusApplication("Google Chrome");
|
|
25
|
+
|
|
26
|
+
const signInButton = await testdriver.find(
|
|
27
|
+
"Sign In, black button below the password field",
|
|
28
|
+
);
|
|
29
|
+
await signInButton.click();
|
|
30
|
+
|
|
31
|
+
const result = await testdriver.assert(
|
|
32
|
+
"an error shows that fields are required",
|
|
33
|
+
);
|
|
34
|
+
expect(result).toBeTruthy();
|
|
35
|
+
|
|
36
|
+
// That's it! Dashcam URL automatically registered with the test run
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Hover Image Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/hover-image.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
8
|
+
import { performLogin } from "./setup/testHelpers.mjs";
|
|
9
|
+
|
|
10
|
+
describe("Hover Image Test", () => {
|
|
11
|
+
it("should click on shopping cart icon and verify empty cart", async (context) => {
|
|
12
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
13
|
+
|
|
14
|
+
// provision.chrome() automatically calls ready() and starts dashcam
|
|
15
|
+
await testdriver.provision.chrome({
|
|
16
|
+
url: 'http://testdriver-sandbox.vercel.app/login',
|
|
17
|
+
});
|
|
18
|
+
|
|
19
|
+
// Perform login first
|
|
20
|
+
await performLogin(testdriver);
|
|
21
|
+
|
|
22
|
+
// Click on the shopping cart icon
|
|
23
|
+
await testdriver.focusApplication("Google Chrome");
|
|
24
|
+
const cartIcon = await testdriver.find(
|
|
25
|
+
"shopping cart icon next to the Cart text in the top right corner",
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
await cartIcon.click();
|
|
29
|
+
|
|
30
|
+
// Assert that you see an empty shopping cart
|
|
31
|
+
const result = await testdriver.assert("Your cart is empty");
|
|
32
|
+
expect(result).toBeTruthy();
|
|
33
|
+
});
|
|
34
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Hover Text With Description Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/hover-text-with-description.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
8
|
+
import { performLogin } from "./setup/testHelpers.mjs";
|
|
9
|
+
|
|
10
|
+
describe("Hover Text With Description Test", () => {
|
|
11
|
+
it("should add TestDriver Hat to cart and verify", async (context) => {
|
|
12
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
13
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
14
|
+
|
|
15
|
+
//
|
|
16
|
+
// Perform login first
|
|
17
|
+
await performLogin(testdriver);
|
|
18
|
+
|
|
19
|
+
// Click on "Add to Cart" under TestDriver Hat
|
|
20
|
+
await testdriver.focusApplication("Google Chrome");
|
|
21
|
+
const addToCartButton = await testdriver.find(
|
|
22
|
+
"Add to Cart, add to cart button under TestDriver Hat",
|
|
23
|
+
);
|
|
24
|
+
await addToCartButton.click();
|
|
25
|
+
|
|
26
|
+
// Click on the cart
|
|
27
|
+
await testdriver.focusApplication("Google Chrome");
|
|
28
|
+
const cartButton = await testdriver.find(
|
|
29
|
+
"Cart, cart button in the top right corner",
|
|
30
|
+
);
|
|
31
|
+
await cartButton.click();
|
|
32
|
+
|
|
33
|
+
// Assert the TestDriver Hat is in the cart
|
|
34
|
+
await testdriver.focusApplication("Google Chrome");
|
|
35
|
+
const result = await testdriver.assert("TestDriver Hat is in the cart");
|
|
36
|
+
expect(result).toBeTruthy();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Hover Text Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/hover-text.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
8
|
+
|
|
9
|
+
describe("Hover Text Test", () => {
|
|
10
|
+
it("should click Sign In and verify error message", async (context) => {
|
|
11
|
+
const testdriver = TestDriver(context, { headless: true, newSandbox: true, cacheKey: 'hover-text-test' });
|
|
12
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
13
|
+
|
|
14
|
+
// Click on Sign In button using new find() API
|
|
15
|
+
|
|
16
|
+
const signInButton = await testdriver.find(
|
|
17
|
+
"Sign In, black button below the password field",
|
|
18
|
+
);
|
|
19
|
+
await signInButton.click();
|
|
20
|
+
|
|
21
|
+
// Assert that an error shows that fields are required
|
|
22
|
+
const result = await testdriver.assert(
|
|
23
|
+
"an error shows that fields are required",
|
|
24
|
+
);
|
|
25
|
+
expect(result).toBeTruthy();
|
|
26
|
+
});
|
|
27
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Match Image Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/match-image.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import path, { dirname } from "path";
|
|
7
|
+
import { fileURLToPath } from "url";
|
|
8
|
+
import { describe, expect, it } from "vitest";
|
|
9
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
10
|
+
import { performLogin } from "./setup/testHelpers.mjs";
|
|
11
|
+
|
|
12
|
+
// Get the directory of the current module
|
|
13
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
14
|
+
const __dirname = dirname(__filename);
|
|
15
|
+
|
|
16
|
+
describe("Match Image Test", () => {
|
|
17
|
+
it("should match shopping cart image and verify empty cart", async (context) => {
|
|
18
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
19
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
20
|
+
|
|
21
|
+
//
|
|
22
|
+
// Perform login first
|
|
23
|
+
await performLogin(testdriver);
|
|
24
|
+
|
|
25
|
+
// Match and click the shopping cart icon
|
|
26
|
+
const cartImagePath = path.resolve(
|
|
27
|
+
__dirname,
|
|
28
|
+
"../../_testdriver/acceptance/screenshots/cart.png",
|
|
29
|
+
);
|
|
30
|
+
await testdriver.matchImage(cartImagePath, "click");
|
|
31
|
+
|
|
32
|
+
// Assert that you see an empty shopping cart
|
|
33
|
+
const result = await testdriver.assert("Your cart is empty");
|
|
34
|
+
expect(result).toBeTruthy();
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Examples demonstrating TestDriver Presets
|
|
3
|
+
*
|
|
4
|
+
* Presets provide pre-configured setups for common applications,
|
|
5
|
+
* reducing boilerplate and making tests easier to write.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { test } from 'vitest';
|
|
9
|
+
import { chromePreset, createPreset, electronPreset, vscodePreset } from '../../src/presets/index.mjs';
|
|
10
|
+
|
|
11
|
+
test('Chrome preset - simple navigation', async (context) => {
|
|
12
|
+
const { browser } = await chromePreset(context, {
|
|
13
|
+
url: 'http://testdriver-sandbox.vercel.app/',
|
|
14
|
+
});
|
|
15
|
+
|
|
16
|
+
// Browser is already open and focused on the URL
|
|
17
|
+
const result = await browser.find('main heading text');
|
|
18
|
+
console.log('Found heading:', result);
|
|
19
|
+
}, 60000);
|
|
20
|
+
|
|
21
|
+
test('Chrome preset - with custom options', async (context) => {
|
|
22
|
+
const { browser, dashcam } = await chromePreset(context, {
|
|
23
|
+
url: 'https://google.com',
|
|
24
|
+
maximized: false,
|
|
25
|
+
guest: false,
|
|
26
|
+
dashcam: true, // Dashcam auto-starts and auto-stops
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
await browser.find('search box').type('testdriverai');
|
|
30
|
+
console.log('Dashcam recording:', dashcam.isRecording());
|
|
31
|
+
}, 60000);
|
|
32
|
+
|
|
33
|
+
test.skip('VS Code preset - basic usage', async (context) => {
|
|
34
|
+
const { vscode } = await vscodePreset(context, {
|
|
35
|
+
workspace: '/tmp/test-project',
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
// VS Code is already open with the workspace loaded
|
|
39
|
+
await vscode.find('File menu').click();
|
|
40
|
+
await vscode.find('New File').click();
|
|
41
|
+
}, 60000);
|
|
42
|
+
|
|
43
|
+
test.skip('VS Code preset - with extensions', async (context) => {
|
|
44
|
+
const { vscode } = await vscodePreset(context, {
|
|
45
|
+
workspace: '/tmp/test-project',
|
|
46
|
+
extensions: ['ms-python.python'],
|
|
47
|
+
dashcam: true,
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
// Extensions are pre-installed, dashcam auto-recording
|
|
51
|
+
await vscode.find('Python extension').click();
|
|
52
|
+
}, 120000);
|
|
53
|
+
|
|
54
|
+
test.skip('Custom preset - Electron app', async (context) => {
|
|
55
|
+
const { app } = await electronPreset(context, {
|
|
56
|
+
appPath: '/path/to/electron/app',
|
|
57
|
+
args: ['--enable-logging'],
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
await app.find('main window').click();
|
|
61
|
+
}, 60000);
|
|
62
|
+
|
|
63
|
+
test.skip('Custom preset - create your own', async (context) => {
|
|
64
|
+
// Create a custom preset for your application
|
|
65
|
+
const firefoxPreset = createPreset({
|
|
66
|
+
name: 'Firefox Browser',
|
|
67
|
+
defaults: { os: 'linux', dashcam: true },
|
|
68
|
+
async setup(context, client, dashcam, options) {
|
|
69
|
+
const { url } = options;
|
|
70
|
+
|
|
71
|
+
// Launch Firefox
|
|
72
|
+
await client.exec('sh', `firefox "${url}" >/dev/null 2>&1 &`, 30000);
|
|
73
|
+
await client.focusApplication('Firefox');
|
|
74
|
+
|
|
75
|
+
return {
|
|
76
|
+
browser: client,
|
|
77
|
+
};
|
|
78
|
+
},
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
// Use your custom preset
|
|
82
|
+
const { browser } = await firefoxPreset(context, {
|
|
83
|
+
url: 'https://example.com',
|
|
84
|
+
});
|
|
85
|
+
|
|
86
|
+
await browser.find('page content').click();
|
|
87
|
+
}, 60000);
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Press Keys Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/press-keys.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
8
|
+
|
|
9
|
+
describe("Press Keys Test", () => {
|
|
10
|
+
it("should create tabs and navigate using keyboard shortcuts", async (context) => {
|
|
11
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
12
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
13
|
+
|
|
14
|
+
const signInButton = await testdriver.find(
|
|
15
|
+
"Sign In, black button below the password field",
|
|
16
|
+
);
|
|
17
|
+
await signInButton.click();
|
|
18
|
+
|
|
19
|
+
// Open new tab
|
|
20
|
+
await testdriver.pressKeys(["ctrl", "t"]);
|
|
21
|
+
|
|
22
|
+
// Poll for "Learn more" to appear
|
|
23
|
+
let learnMore = await testdriver.find("Learn more");
|
|
24
|
+
for (let i = 0; i < 10; i++) {
|
|
25
|
+
learnMore = await learnMore.find();
|
|
26
|
+
if (learnMore.found()) break;
|
|
27
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
// Open DevTools
|
|
31
|
+
await testdriver.pressKeys(["ctrl", "shift", "i"]);
|
|
32
|
+
|
|
33
|
+
// Poll for "Elements" to appear
|
|
34
|
+
let elements = await testdriver.find("Elements");
|
|
35
|
+
for (let i = 0; i < 10; i++) {
|
|
36
|
+
elements = await elements.find();
|
|
37
|
+
if (elements.found()) break;
|
|
38
|
+
await new Promise((resolve) => setTimeout(resolve, 500));
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
// Open another tab and navigate
|
|
42
|
+
await testdriver.pressKeys(["ctrl", "t"]);
|
|
43
|
+
await testdriver.type("google.com");
|
|
44
|
+
await testdriver.pressKeys(["enter"]);
|
|
45
|
+
|
|
46
|
+
// Assert Google appears
|
|
47
|
+
const result = await testdriver.assert("google appears");
|
|
48
|
+
expect(result).toBeTruthy();
|
|
49
|
+
});
|
|
50
|
+
});
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Prompt Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/prompt.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
8
|
+
|
|
9
|
+
describe.skip("Prompt Test", () => {
|
|
10
|
+
it("should execute AI-driven prompts", async (context) => {
|
|
11
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
12
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
13
|
+
|
|
14
|
+
//
|
|
15
|
+
// Note: The SDK doesn't have a direct equivalent to YAML prompts without commands.
|
|
16
|
+
// This would typically be handled by the AI agent interpreting natural language.
|
|
17
|
+
// For SDK usage, you need to use explicit commands.
|
|
18
|
+
|
|
19
|
+
// Original prompts were:
|
|
20
|
+
// 1. "log in"
|
|
21
|
+
// 2. "add an item to the cart"
|
|
22
|
+
// 3. "click on the cart icon"
|
|
23
|
+
// 4. "complete checkout"
|
|
24
|
+
|
|
25
|
+
// This test is skipped as it requires explicit SDK implementation
|
|
26
|
+
// You would need to implement these as explicit SDK calls
|
|
27
|
+
|
|
28
|
+
await testdriver.ai("log in");
|
|
29
|
+
|
|
30
|
+
const result = await testdriver.assert("the testdriver sandbox is visible");
|
|
31
|
+
expect(result).toBeTruthy();
|
|
32
|
+
});
|
|
33
|
+
});
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Scroll Keyboard Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/scroll-keyboard.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
8
|
+
|
|
9
|
+
describe("Scroll Keyboard Test", () => {
|
|
10
|
+
it("should navigate to webhamster.com and scroll with keyboard", async (context) => {
|
|
11
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
12
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
13
|
+
|
|
14
|
+
//
|
|
15
|
+
// Navigate to https://www.webhamster.com/
|
|
16
|
+
await testdriver.focusApplication("Google Chrome");
|
|
17
|
+
const urlBar = await testdriver.find(
|
|
18
|
+
"testdriver-sandbox.vercel.app/login, the URL in the omnibox showing the current page",
|
|
19
|
+
);
|
|
20
|
+
await urlBar.click();
|
|
21
|
+
await testdriver.pressKeys(["ctrl", "a"]);
|
|
22
|
+
await testdriver.type("https://www.webhamster.com/");
|
|
23
|
+
await testdriver.pressKeys(["enter"]);
|
|
24
|
+
|
|
25
|
+
// Scroll down with keyboard 1000 pixels
|
|
26
|
+
const heading = await testdriver.find(
|
|
27
|
+
"The Hamster Dance, large heading at top of page",
|
|
28
|
+
);
|
|
29
|
+
await heading.click();
|
|
30
|
+
await testdriver.scroll("down", 1000);
|
|
31
|
+
|
|
32
|
+
// Assert the page is scrolled down
|
|
33
|
+
const result = await testdriver.assert(
|
|
34
|
+
"the hamster dance heading is not visible",
|
|
35
|
+
);
|
|
36
|
+
expect(result).toBeTruthy();
|
|
37
|
+
});
|
|
38
|
+
});
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Scroll Until Image Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/scroll-until-image.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
8
|
+
|
|
9
|
+
describe("Scroll Until Image Test", () => {
|
|
10
|
+
it("should scroll until brown colored house image appears", async (context) => {
|
|
11
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
12
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
13
|
+
|
|
14
|
+
//
|
|
15
|
+
// Navigate to Wikipedia page
|
|
16
|
+
await testdriver.pressKeys(["ctrl", "l"]);
|
|
17
|
+
await testdriver.type("https://en.wikipedia.org/wiki/Leonardo_da_Vinci");
|
|
18
|
+
await testdriver.pressKeys(["enter"]);
|
|
19
|
+
|
|
20
|
+
// sleep for 5 seconds
|
|
21
|
+
await new Promise((r) => setTimeout(r, 5000));
|
|
22
|
+
|
|
23
|
+
// Click on heading
|
|
24
|
+
const heading = await testdriver.find(
|
|
25
|
+
"Leonardo Da Vinci, the page heading",
|
|
26
|
+
0,
|
|
27
|
+
);
|
|
28
|
+
await heading.click();
|
|
29
|
+
|
|
30
|
+
// Scroll until image appears
|
|
31
|
+
await testdriver.scrollUntilImage("a brown colored house", "down", 10000);
|
|
32
|
+
|
|
33
|
+
// Assert image of brown colored house appears on screen
|
|
34
|
+
const result = await testdriver.assert(
|
|
35
|
+
"image of brown colored house appears on screen",
|
|
36
|
+
);
|
|
37
|
+
expect(result).toBeTruthy();
|
|
38
|
+
});
|
|
39
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Scroll Until Text Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/scroll-until-text.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
8
|
+
import { performLogin } from "./setup/testHelpers.mjs";
|
|
9
|
+
|
|
10
|
+
describe("Scroll Until Text Test", () => {
|
|
11
|
+
it('should scroll until "testdriver socks" appears', async (context) => {
|
|
12
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
13
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
14
|
+
|
|
15
|
+
//
|
|
16
|
+
// Perform login first
|
|
17
|
+
await performLogin(testdriver);
|
|
18
|
+
|
|
19
|
+
// Scroll until text appears
|
|
20
|
+
await testdriver.focusApplication("Google Chrome");
|
|
21
|
+
await testdriver.scrollUntilText({ text: "testdriver socks", direction: "down" });
|
|
22
|
+
|
|
23
|
+
// Assert testdriver socks appears on screen
|
|
24
|
+
await testdriver.focusApplication("Google Chrome");
|
|
25
|
+
const result = await testdriver.assert("TestDriver Socks appears on screen");
|
|
26
|
+
expect(result).toBeTruthy();
|
|
27
|
+
});
|
|
28
|
+
});
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Scroll Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/scroll.yaml
|
|
4
|
+
*
|
|
5
|
+
* UPDATED: Now using chrome preset for automatic setup
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { describe, expect, it } from "vitest";
|
|
9
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
10
|
+
|
|
11
|
+
describe("Scroll Test", () => {
|
|
12
|
+
it("should navigate and scroll down the page", async (context) => {
|
|
13
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
14
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
15
|
+
|
|
16
|
+
// Give Chrome a moment to fully render the UI
|
|
17
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
18
|
+
|
|
19
|
+
// Navigate to webhamster.com - just look for the domain, not the full path
|
|
20
|
+
const urlBar = await testdriver.find(
|
|
21
|
+
"testdriver-sandbox.vercel.app, the URL in the address bar",
|
|
22
|
+
);
|
|
23
|
+
await urlBar.click();
|
|
24
|
+
await testdriver.pressKeys(["ctrl", "a"]);
|
|
25
|
+
await testdriver.type("https://www.webhamster.com/");
|
|
26
|
+
await testdriver.pressKeys(["enter"]);
|
|
27
|
+
|
|
28
|
+
// Wait for page to load and click heading
|
|
29
|
+
const heading = await testdriver.find(
|
|
30
|
+
"The Hamster Dance, large heading at top of page",
|
|
31
|
+
);
|
|
32
|
+
await heading.click();
|
|
33
|
+
|
|
34
|
+
// Scroll down
|
|
35
|
+
await testdriver.scroll("down", 1000);
|
|
36
|
+
|
|
37
|
+
// Assert page is scrolled
|
|
38
|
+
const result = await testdriver.assert("the page is scrolled down, the hamster dance heading is not visible on the page");
|
|
39
|
+
expect(result).toBeTruthy();
|
|
40
|
+
});
|
|
41
|
+
});
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Vitest Global Teardown
|
|
3
|
+
* Saves test results and dashcam URLs after all tests complete
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { saveTestResults } from "./testHelpers.mjs";
|
|
7
|
+
|
|
8
|
+
export default async function globalTeardown() {
|
|
9
|
+
console.log("\n🎬 Saving test results and dashcam URLs...");
|
|
10
|
+
saveTestResults();
|
|
11
|
+
}
|