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,245 @@
|
|
|
1
|
+
# TestDriver SDK Test Reporting
|
|
2
|
+
|
|
3
|
+
This guide explains the enhanced test reporting system for the TestDriver SDK acceptance tests.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
The SDK tests use **Vitest** with multiple reporters to provide comprehensive test feedback:
|
|
8
|
+
|
|
9
|
+
1. **Console Output** - Verbose, detailed logs during test execution
|
|
10
|
+
2. **JUnit XML** - For CI/CD integration and third-party tools
|
|
11
|
+
3. **JSON Results** - Machine-readable format for custom reporting
|
|
12
|
+
4. **HTML Report** - Interactive browser-based test results viewer
|
|
13
|
+
5. **GitHub Summary** - Markdown tables in GitHub Actions workflow summaries
|
|
14
|
+
|
|
15
|
+
## Running Tests Locally
|
|
16
|
+
|
|
17
|
+
### Basic Test Run
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm run test:sdk
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
This runs all SDK acceptance tests with verbose output.
|
|
24
|
+
|
|
25
|
+
### Watch Mode (for development)
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
npm run test:sdk:watch
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Re-runs tests automatically when files change.
|
|
32
|
+
|
|
33
|
+
### Interactive UI
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
npm run test:sdk:ui
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
Opens Vitest's web UI for interactive test exploration.
|
|
40
|
+
|
|
41
|
+
### View Results After Running Tests
|
|
42
|
+
|
|
43
|
+
After running tests, you have several options to view results:
|
|
44
|
+
|
|
45
|
+
#### Terminal Summary
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
npm run test:sdk:results
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Displays a formatted summary in your terminal with:
|
|
52
|
+
|
|
53
|
+
- ✅ Passed test count
|
|
54
|
+
- ❌ Failed test count and error details
|
|
55
|
+
- ⏱️ Test duration
|
|
56
|
+
- 📁 File-by-file breakdown
|
|
57
|
+
|
|
58
|
+
#### HTML Report (Best for detailed analysis)
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
npm run test:sdk:report
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Opens the interactive HTML report in your browser showing:
|
|
65
|
+
|
|
66
|
+
- Detailed test execution timeline
|
|
67
|
+
- File-by-file results
|
|
68
|
+
- Error stack traces with code context
|
|
69
|
+
- Test duration metrics
|
|
70
|
+
|
|
71
|
+
Or manually open: `test-results/index.html`
|
|
72
|
+
|
|
73
|
+
## GitHub Actions Reporting
|
|
74
|
+
|
|
75
|
+
When tests run in GitHub Actions, you get enhanced reporting automatically:
|
|
76
|
+
|
|
77
|
+
### 📊 GitHub Step Summary
|
|
78
|
+
|
|
79
|
+
The workflow generates a comprehensive summary visible in the Actions run:
|
|
80
|
+
|
|
81
|
+
- **Overview Table**: Pass/fail counts, duration, and totals
|
|
82
|
+
- **Failed Tests Section**: Each failure with error messages and stack traces
|
|
83
|
+
- **Passed Tests Section**: List of all passing tests organized by file
|
|
84
|
+
|
|
85
|
+
To view: Go to the Actions tab → Select your workflow run → Check the "Summary" section
|
|
86
|
+
|
|
87
|
+
### 🧪 Test Summary Action
|
|
88
|
+
|
|
89
|
+
The `test-summary/action` provides:
|
|
90
|
+
|
|
91
|
+
- Test count badges
|
|
92
|
+
- Duration metrics
|
|
93
|
+
- Failure annotations in the Files Changed tab
|
|
94
|
+
|
|
95
|
+
### 📦 Test Artifacts
|
|
96
|
+
|
|
97
|
+
All test results are uploaded as artifacts (retained for 7 days):
|
|
98
|
+
|
|
99
|
+
- `junit.xml` - JUnit format for third-party tools
|
|
100
|
+
- `results.json` - Machine-readable JSON
|
|
101
|
+
- `index.html` - Interactive HTML report (download and open locally)
|
|
102
|
+
|
|
103
|
+
To download artifacts:
|
|
104
|
+
|
|
105
|
+
1. Go to the workflow run
|
|
106
|
+
2. Scroll to "Artifacts" section at the bottom
|
|
107
|
+
3. Download `test-results.zip`
|
|
108
|
+
|
|
109
|
+
## Test Output Files
|
|
110
|
+
|
|
111
|
+
All test results are saved to the `test-results/` directory:
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
test-results/
|
|
115
|
+
├── junit.xml # JUnit XML format
|
|
116
|
+
├── results.json # Detailed JSON results
|
|
117
|
+
└── index.html # Interactive HTML report
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
Add this to your `.gitignore`:
|
|
121
|
+
|
|
122
|
+
```
|
|
123
|
+
test-results/
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## Reporters Explained
|
|
127
|
+
|
|
128
|
+
### 1. Verbose Reporter (Console)
|
|
129
|
+
|
|
130
|
+
- Shows full test logs in real-time
|
|
131
|
+
- Includes console.log output from tests
|
|
132
|
+
- Color-coded pass/fail indicators
|
|
133
|
+
- Stack traces for failures
|
|
134
|
+
|
|
135
|
+
### 2. JUnit Reporter
|
|
136
|
+
|
|
137
|
+
- Industry-standard XML format
|
|
138
|
+
- Compatible with Jenkins, Azure DevOps, etc.
|
|
139
|
+
- Used by `test-summary/action`
|
|
140
|
+
|
|
141
|
+
### 3. JSON Reporter
|
|
142
|
+
|
|
143
|
+
- Complete test results in JSON format
|
|
144
|
+
- Programmatically parseable
|
|
145
|
+
- Used by the custom results viewer script
|
|
146
|
+
|
|
147
|
+
### 4. HTML Reporter
|
|
148
|
+
|
|
149
|
+
- Interactive web-based viewer
|
|
150
|
+
- Visual timeline of test execution
|
|
151
|
+
- Filterable and searchable results
|
|
152
|
+
- Best for debugging failures locally
|
|
153
|
+
|
|
154
|
+
## Customizing Test Output
|
|
155
|
+
|
|
156
|
+
### Run a Single Test File
|
|
157
|
+
|
|
158
|
+
```bash
|
|
159
|
+
npx vitest run testdriver/acceptance-sdk/assert.test.mjs
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
### Enable Even More Verbose Logging
|
|
163
|
+
|
|
164
|
+
```bash
|
|
165
|
+
VERBOSE=true LOGGING=true npm run test:sdk
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### Change Parallelism
|
|
169
|
+
|
|
170
|
+
Edit `vitest.config.mjs`:
|
|
171
|
+
|
|
172
|
+
```javascript
|
|
173
|
+
maxForks: 5, // Run 5 tests in parallel instead of 10
|
|
174
|
+
```
|
|
175
|
+
|
|
176
|
+
## Troubleshooting
|
|
177
|
+
|
|
178
|
+
### "No test results found" error
|
|
179
|
+
|
|
180
|
+
Make sure you've run the tests first:
|
|
181
|
+
|
|
182
|
+
```bash
|
|
183
|
+
npm run test:sdk
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
### HTML report won't open
|
|
187
|
+
|
|
188
|
+
Manually navigate to and open `test-results/index.html` in your browser.
|
|
189
|
+
|
|
190
|
+
### Tests timeout
|
|
191
|
+
|
|
192
|
+
Increase timeout in `vitest.config.mjs`:
|
|
193
|
+
|
|
194
|
+
```javascript
|
|
195
|
+
testTimeout: 900000, // 15 minutes
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
## Best Practices
|
|
199
|
+
|
|
200
|
+
1. **Use `test:sdk:results`** for quick terminal summaries
|
|
201
|
+
2. **Use `test:sdk:report`** for deep debugging of failures
|
|
202
|
+
3. **Check GitHub Summary** in PR reviews for test status
|
|
203
|
+
4. **Download artifacts** from GitHub Actions for historical analysis
|
|
204
|
+
5. **Run `test:sdk:watch`** during development for fast feedback
|
|
205
|
+
|
|
206
|
+
## Example GitHub Summary Output
|
|
207
|
+
|
|
208
|
+
```markdown
|
|
209
|
+
# 🧪 TestDriver SDK Test Results
|
|
210
|
+
|
|
211
|
+
## 📊 Overview
|
|
212
|
+
|
|
213
|
+
| Metric | Count |
|
|
214
|
+
| ----------- | ------- |
|
|
215
|
+
| ✅ Passed | 18 |
|
|
216
|
+
| ❌ Failed | 2 |
|
|
217
|
+
| ⏭️ Skipped | 0 |
|
|
218
|
+
| 📝 Total | 20 |
|
|
219
|
+
| ⏱️ Duration | 145.23s |
|
|
220
|
+
|
|
221
|
+
## ❌ Failed Tests
|
|
222
|
+
|
|
223
|
+
### Assert Test > should assert the testdriver login page shows
|
|
224
|
+
|
|
225
|
+
**File:** `testdriver/acceptance-sdk/assert.test.mjs`
|
|
226
|
+
|
|
227
|
+
**Error:**
|
|
228
|
+
```
|
|
229
|
+
|
|
230
|
+
AssertionError: expected false to be truthy
|
|
231
|
+
|
|
232
|
+
```
|
|
233
|
+
|
|
234
|
+
## ✅ Passed Tests
|
|
235
|
+
|
|
236
|
+
### type.test.mjs
|
|
237
|
+
- ✅ should type text into input field
|
|
238
|
+
- ✅ should clear and retype text
|
|
239
|
+
|
|
240
|
+
### scroll.test.mjs
|
|
241
|
+
- ✅ should scroll down the page
|
|
242
|
+
- ✅ should scroll to specific element
|
|
243
|
+
```
|
|
244
|
+
|
|
245
|
+
This summary appears automatically in every GitHub Actions workflow run!
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Assert Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/assert.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
8
|
+
|
|
9
|
+
describe("Assert Test", () => {
|
|
10
|
+
it("should assert the testdriver login page shows", async (context) => {
|
|
11
|
+
const testdriver = TestDriver(context, { headless: true, newSandbox: true });
|
|
12
|
+
|
|
13
|
+
// provision.chrome() automatically calls ready() and starts dashcam
|
|
14
|
+
await testdriver.provision.chrome({
|
|
15
|
+
url: 'http://testdriver-sandbox.vercel.app/login',
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
// Assert the TestDriver.ai Sandbox login page is displayed
|
|
19
|
+
const result = await testdriver.assert(
|
|
20
|
+
"the TestDriver.ai Sandbox login page is displayed",
|
|
21
|
+
);
|
|
22
|
+
|
|
23
|
+
expect(result).toBeTruthy();
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Auto Cache Key Demo
|
|
3
|
+
*
|
|
4
|
+
* This test demonstrates the auto-generated cache key feature.
|
|
5
|
+
* When no cacheKey is provided, TestDriver will automatically generate
|
|
6
|
+
* one based on the hash of this test file.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { describe, expect, it } from "vitest";
|
|
10
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
11
|
+
|
|
12
|
+
describe("Auto Cache Key Demo", () => {
|
|
13
|
+
it("should use auto-generated cache key based on file hash", async (context) => {
|
|
14
|
+
// NOTE: No cacheKey is provided here!
|
|
15
|
+
// TestDriver will automatically generate one from the hash of this file
|
|
16
|
+
const testdriver = TestDriver(context, {
|
|
17
|
+
headless: true,
|
|
18
|
+
newSandbox: true
|
|
19
|
+
// cacheKey NOT specified - will be auto-generated
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
// The cache key should be auto-generated
|
|
23
|
+
console.log('Auto-generated cache key:', testdriver.options.cacheKey);
|
|
24
|
+
expect(testdriver.options.cacheKey).toBeTruthy();
|
|
25
|
+
expect(testdriver.options.cacheKey).toMatch(/^[0-9a-f]{16}$/); // 16 hex chars
|
|
26
|
+
|
|
27
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
28
|
+
|
|
29
|
+
// First find - will be cached with auto-generated key
|
|
30
|
+
const signInButton1 = await testdriver.find(
|
|
31
|
+
"Sign In, black button below the password field"
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
// Second find - should hit cache because it's the same file (same cache key)
|
|
35
|
+
const signInButton2 = await testdriver.find(
|
|
36
|
+
"Sign In, black button below the password field"
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
expect(signInButton1.found()).toBe(true);
|
|
40
|
+
expect(signInButton2.found()).toBe(true);
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
it("should use same auto-generated cache key for multiple tests in the same file", async (context) => {
|
|
44
|
+
// This test is in the same file, so it should get the same auto-generated cache key
|
|
45
|
+
const testdriver = TestDriver(context, {
|
|
46
|
+
headless: true,
|
|
47
|
+
newSandbox: true
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
console.log('Auto-generated cache key (test 2):', testdriver.options.cacheKey);
|
|
51
|
+
expect(testdriver.options.cacheKey).toBeTruthy();
|
|
52
|
+
|
|
53
|
+
// If you modify this file, the hash (and therefore cache key) will change,
|
|
54
|
+
// invalidating the cache for this test file
|
|
55
|
+
});
|
|
56
|
+
});
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Chrome Extension Loading Demo
|
|
3
|
+
* Demonstrates how to load Chrome extensions using Chrome for Testing
|
|
4
|
+
*
|
|
5
|
+
* This test shows how to launch Chrome with a specific extension loaded
|
|
6
|
+
* by using its Chrome Web Store extension ID.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { afterAll, beforeAll, describe, expect, it } from "vitest";
|
|
10
|
+
import TestDriver from "../../sdk.js";
|
|
11
|
+
import {
|
|
12
|
+
runPostrun,
|
|
13
|
+
runPrerunChromeExtension
|
|
14
|
+
} from "./setup/lifecycleHelpers.mjs";
|
|
15
|
+
|
|
16
|
+
describe("Chrome Extension Loading", () => {
|
|
17
|
+
let client;
|
|
18
|
+
let dashcamUrl;
|
|
19
|
+
|
|
20
|
+
beforeAll(async () => {
|
|
21
|
+
// Initialize TestDriver client
|
|
22
|
+
client = await TestDriver.create({
|
|
23
|
+
apiKey: process.env.TD_API_KEY,
|
|
24
|
+
apiRoot: process.env.TD_API_ROOT,
|
|
25
|
+
os: "linux",
|
|
26
|
+
verbosity: 1,
|
|
27
|
+
});
|
|
28
|
+
|
|
29
|
+
// Run prerun with uBlock Origin extension loaded
|
|
30
|
+
// Extension ID: cjpalhdlnbpafiamejdnhcphjbkeiagm
|
|
31
|
+
await runPrerunChromeExtension(client, "cjpalhdlnbpafiamejdnhcphjbkeiagm");
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
afterAll(async () => {
|
|
35
|
+
if (client) {
|
|
36
|
+
dashcamUrl = await runPostrun(client);
|
|
37
|
+
await client.cleanup();
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
it("should load Chrome with extension and verify functionality", async () => {
|
|
42
|
+
// Focus Chrome browser
|
|
43
|
+
await client.focusApplication("Google Chrome");
|
|
44
|
+
|
|
45
|
+
// Verify the page loaded
|
|
46
|
+
const pageElement = await client.find("TestDriver.ai Sandbox");
|
|
47
|
+
expect(pageElement.found()).toBe(true);
|
|
48
|
+
|
|
49
|
+
// Test basic interaction to ensure Chrome is working with the extension
|
|
50
|
+
const signInButton = await client.find(
|
|
51
|
+
"Sign In, black button below the password field",
|
|
52
|
+
);
|
|
53
|
+
await signInButton.click();
|
|
54
|
+
|
|
55
|
+
// Verify error message appears
|
|
56
|
+
const result = await client.assert(
|
|
57
|
+
"an error shows that fields are required",
|
|
58
|
+
);
|
|
59
|
+
expect(result).toBeTruthy();
|
|
60
|
+
|
|
61
|
+
console.log("✅ Chrome extension loaded successfully!");
|
|
62
|
+
if (dashcamUrl) {
|
|
63
|
+
console.log("🎥 Dashcam URL:", dashcamUrl);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
|
|
67
|
+
it("should demonstrate extension interaction", async () => {
|
|
68
|
+
// You can add specific tests here to interact with the extension
|
|
69
|
+
// For example, if testing uBlock Origin, you might:
|
|
70
|
+
// 1. Navigate to a page with ads
|
|
71
|
+
// 2. Verify ads are blocked
|
|
72
|
+
// 3. Access the extension's popup or settings
|
|
73
|
+
|
|
74
|
+
await client.focusApplication("Google Chrome");
|
|
75
|
+
|
|
76
|
+
// Example: Navigate to extension management page to verify it's loaded
|
|
77
|
+
await client.exec(
|
|
78
|
+
"sh",
|
|
79
|
+
`xdotool key --clearmodifiers ctrl+shift+e`,
|
|
80
|
+
5000,
|
|
81
|
+
true
|
|
82
|
+
);
|
|
83
|
+
|
|
84
|
+
// Wait a moment for the extensions page to potentially load
|
|
85
|
+
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
86
|
+
|
|
87
|
+
console.log("✅ Extension interaction test completed");
|
|
88
|
+
});
|
|
89
|
+
});
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Drag and Drop Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/drag-and-drop.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
8
|
+
|
|
9
|
+
const isLinux = (process.env.TD_OS || "linux") === "linux";
|
|
10
|
+
|
|
11
|
+
describe("Drag and Drop Test", () => {
|
|
12
|
+
it.skipIf(isLinux)(
|
|
13
|
+
'should drag "New Text Document" to "Recycle Bin"',
|
|
14
|
+
async (context) => {
|
|
15
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
16
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
17
|
+
|
|
18
|
+
//
|
|
19
|
+
// Show the desktop
|
|
20
|
+
await testdriver.pressKeys(["win", "d"]);
|
|
21
|
+
|
|
22
|
+
// Open the context menu
|
|
23
|
+
await testdriver.pressKeys(["shift", "f10"]);
|
|
24
|
+
|
|
25
|
+
// Hover over "New" in the context menu
|
|
26
|
+
const newOption = await testdriver.find(
|
|
27
|
+
"New, new option in the open context menu on the desktop",
|
|
28
|
+
);
|
|
29
|
+
await newOption.hover();
|
|
30
|
+
|
|
31
|
+
// Click "Text Document" in the context menu
|
|
32
|
+
const textDocOption = await testdriver.find(
|
|
33
|
+
"Text Document, text document option in the new submenu of the desktop context menu",
|
|
34
|
+
);
|
|
35
|
+
await textDocOption.click();
|
|
36
|
+
|
|
37
|
+
// Unfocus the "Text Document" text field
|
|
38
|
+
await testdriver.pressKeys(["esc"]);
|
|
39
|
+
|
|
40
|
+
// Drag the "New Text Document" icon to the "Recycle Bin"
|
|
41
|
+
const textDoc = await testdriver.find(
|
|
42
|
+
"New Text Document, new text document icon in the center of the desktop",
|
|
43
|
+
);
|
|
44
|
+
await textDoc.mouseDown();
|
|
45
|
+
|
|
46
|
+
const recycleBin = await testdriver.find(
|
|
47
|
+
"Recycle Bin, recycle bin icon in the top left corner of the desktop",
|
|
48
|
+
);
|
|
49
|
+
await recycleBin.mouseUp();
|
|
50
|
+
|
|
51
|
+
// Assert "New Text Document" icon is not on the Desktop
|
|
52
|
+
const result = await testdriver.assert(
|
|
53
|
+
'the "New Text Document" icon is not visible on the Desktop',
|
|
54
|
+
);
|
|
55
|
+
expect(result).toBeTruthy();
|
|
56
|
+
},
|
|
57
|
+
);
|
|
58
|
+
});
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Element Not Found Test
|
|
3
|
+
* Tests that finding a non-existent element returns properly without timing out
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
8
|
+
|
|
9
|
+
describe("Element Not Found Test", () => {
|
|
10
|
+
it("should handle non-existent element gracefully without timing out", async (context) => {
|
|
11
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
12
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
13
|
+
|
|
14
|
+
//
|
|
15
|
+
|
|
16
|
+
// Try to find an element that definitely doesn't exist
|
|
17
|
+
const element = await testdriver.find(
|
|
18
|
+
"a purple unicorn dancing on the moon",
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
// Should return an element that is not found
|
|
22
|
+
expect(element.found()).toBe(false);
|
|
23
|
+
expect(element.coordinates).toBeNull();
|
|
24
|
+
}, 90000); // 90 second timeout for the test (should complete much faster)
|
|
25
|
+
});
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Exec JS Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/exec-js.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
8
|
+
|
|
9
|
+
describe("Exec JavaScript Test", () => {
|
|
10
|
+
it("should fetch user data from API and enter email", async (context) => {
|
|
11
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
12
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
13
|
+
|
|
14
|
+
//
|
|
15
|
+
// Execute JavaScript to fetch user data
|
|
16
|
+
const userEmail = await testdriver.exec(
|
|
17
|
+
"js",
|
|
18
|
+
`
|
|
19
|
+
const response = await fetch('https://jsonplaceholder.typicode.com/users');
|
|
20
|
+
const user = await response.json();
|
|
21
|
+
console.log('user', user[0]);
|
|
22
|
+
result = user[0].email;
|
|
23
|
+
`,
|
|
24
|
+
10000,
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
expect(userEmail).toBeTruthy();
|
|
28
|
+
expect(userEmail).toContain("@");
|
|
29
|
+
|
|
30
|
+
// Enter email in username field
|
|
31
|
+
const usernameField = await testdriver.find(
|
|
32
|
+
"Username, input field for username",
|
|
33
|
+
);
|
|
34
|
+
await usernameField.click();
|
|
35
|
+
await testdriver.type(userEmail);
|
|
36
|
+
|
|
37
|
+
// Assert email is in the field
|
|
38
|
+
const result = await testdriver.assert(
|
|
39
|
+
'the username field contains "Sincere@april.biz" which is a valid email address',
|
|
40
|
+
);
|
|
41
|
+
expect(result).toBeTruthy();
|
|
42
|
+
});
|
|
43
|
+
});
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Exec Output Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/exec-output.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
8
|
+
|
|
9
|
+
describe("Exec Output Test", () => {
|
|
10
|
+
it.skipIf(process.env.TD_OS === "linux")(
|
|
11
|
+
"should set date using PowerShell and navigate to calendar",
|
|
12
|
+
async (context) => {
|
|
13
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
14
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
15
|
+
|
|
16
|
+
//
|
|
17
|
+
// Generate date in query string format
|
|
18
|
+
const queryString = await testdriver.exec(
|
|
19
|
+
"pwsh",
|
|
20
|
+
`
|
|
21
|
+
$date = (Get-Date).AddMonths(1)
|
|
22
|
+
Write-Output $date.ToString("yyyy-MM-dd")
|
|
23
|
+
`,
|
|
24
|
+
10000,
|
|
25
|
+
);
|
|
26
|
+
|
|
27
|
+
// Assert that the date is valid
|
|
28
|
+
const dateValidResult = await testdriver.assert(
|
|
29
|
+
`${queryString} is a valid date`,
|
|
30
|
+
);
|
|
31
|
+
expect(dateValidResult).toBeTruthy();
|
|
32
|
+
|
|
33
|
+
// Generate date in display format
|
|
34
|
+
const expectedDate = await testdriver.exec(
|
|
35
|
+
"pwsh",
|
|
36
|
+
`
|
|
37
|
+
$date = (Get-Date).AddMonths(1)
|
|
38
|
+
Write-Output $date.ToString("ddd MMM d yyyy")
|
|
39
|
+
`,
|
|
40
|
+
10000,
|
|
41
|
+
);
|
|
42
|
+
|
|
43
|
+
// Navigate to calendar with date parameter
|
|
44
|
+
await testdriver.focusApplication("Google Chrome");
|
|
45
|
+
await testdriver.pressKeys(["ctrl", "l"]);
|
|
46
|
+
await testdriver.type(
|
|
47
|
+
`https://teamup.com/ks48cf2135e7e080bc?view=d&date=${queryString}`,
|
|
48
|
+
);
|
|
49
|
+
await testdriver.pressKeys(["enter"]);
|
|
50
|
+
|
|
51
|
+
// Assert that the expected date shows
|
|
52
|
+
await testdriver.focusApplication("Google Chrome");
|
|
53
|
+
const result = await testdriver.assert(
|
|
54
|
+
`the text ${expectedDate} is visible on screen`,
|
|
55
|
+
);
|
|
56
|
+
expect(result).toBeTruthy();
|
|
57
|
+
},
|
|
58
|
+
);
|
|
59
|
+
});
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Exec Shell Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/exec-shell.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
8
|
+
|
|
9
|
+
describe("Exec PowerShell Test", () => {
|
|
10
|
+
it.skipIf(process.env.TD_OS === "linux")(
|
|
11
|
+
"should generate random email using PowerShell and enter it",
|
|
12
|
+
async (context) => {
|
|
13
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
14
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
15
|
+
|
|
16
|
+
//
|
|
17
|
+
// Generate random email using PowerShell
|
|
18
|
+
const randomEmail = await testdriver.exec({
|
|
19
|
+
language: "pwsh",
|
|
20
|
+
code: `
|
|
21
|
+
# Random email generator in PowerShell
|
|
22
|
+
|
|
23
|
+
# Arrays of possible names and domains
|
|
24
|
+
$firstNames = @("john", "jane", "alex", "chris", "sara", "mike", "lisa", "david", "emma", "ryan")
|
|
25
|
+
$lastNames = @("smith", "johnson", "williams", "brown", "jones", "garcia", "miller", "davis", "martin", "lee")
|
|
26
|
+
$domains = @("example.com", "testmail.com", "mailinator.com", "demo.org", "company.net")
|
|
27
|
+
|
|
28
|
+
# Random selection
|
|
29
|
+
$first = Get-Random -InputObject $firstNames
|
|
30
|
+
$last = Get-Random -InputObject $lastNames
|
|
31
|
+
$domain = Get-Random -InputObject $domains
|
|
32
|
+
$number = Get-Random -Minimum 1 -Maximum 1000
|
|
33
|
+
|
|
34
|
+
# Generate the email
|
|
35
|
+
$email = "$first.$last$number@$domain".ToLower()
|
|
36
|
+
|
|
37
|
+
# Output
|
|
38
|
+
Write-Output "$email"
|
|
39
|
+
`,
|
|
40
|
+
timeout: 10000,
|
|
41
|
+
});
|
|
42
|
+
|
|
43
|
+
// Enter the email in username field
|
|
44
|
+
const usernameField = await testdriver.find(
|
|
45
|
+
"Username, input field for username",
|
|
46
|
+
);
|
|
47
|
+
await usernameField.click();
|
|
48
|
+
await testdriver.type(randomEmail);
|
|
49
|
+
|
|
50
|
+
// Assert that the username field shows a valid email address
|
|
51
|
+
const result = await testdriver.assert(
|
|
52
|
+
`the username field contains ${randomEmail} which is a valid email address`,
|
|
53
|
+
);
|
|
54
|
+
expect(result).toBeTruthy();
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Focus Window Test (Vitest)
|
|
3
|
+
* Converted from: testdriver/acceptance/focus-window.yaml
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
8
|
+
|
|
9
|
+
describe("Focus Window Test", () => {
|
|
10
|
+
it.skipIf(process.env.TD_OS === "linux")(
|
|
11
|
+
"should click Microsoft Edge icon and focus Google Chrome",
|
|
12
|
+
async (context) => {
|
|
13
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
14
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
15
|
+
|
|
16
|
+
//
|
|
17
|
+
// Show desktop
|
|
18
|
+
await testdriver.pressKeys(["winleft", "d"]);
|
|
19
|
+
|
|
20
|
+
// Click on the Microsoft Edge icon
|
|
21
|
+
const edgeIcon = await testdriver.find(
|
|
22
|
+
"a blue and green swirl icon on the taskbar representing Microsoft Edge",
|
|
23
|
+
);
|
|
24
|
+
await edgeIcon.click();
|
|
25
|
+
|
|
26
|
+
// Focus Google Chrome
|
|
27
|
+
await testdriver.focusApplication("Google Chrome");
|
|
28
|
+
|
|
29
|
+
// Assert Chrome is focused (implicit through successful focus)
|
|
30
|
+
const result = await testdriver.assert(
|
|
31
|
+
"Google Chrome is the focused application",
|
|
32
|
+
);
|
|
33
|
+
expect(result).toBeTruthy();
|
|
34
|
+
},
|
|
35
|
+
);
|
|
36
|
+
});
|