testdriverai 7.3.1 → 7.3.3
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/.claude/settings.local.json +7 -0
- package/.env.example +4 -0
- package/.github/workflows/acceptance-linux-scheduled.yaml +45 -0
- package/.github/workflows/acceptance-windows-scheduled.yaml +54 -0
- package/.github/workflows/acceptance.yaml +106 -0
- package/.github/workflows/publish.yaml +75 -0
- package/.github/workflows/test-init.yml +157 -0
- package/.github/workflows/testdriver.yml +170 -0
- package/.github/workflows/windows-self-hosted.yaml +82 -0
- package/.prettierignore +4 -0
- package/.prettierrc +1 -0
- package/CHANGELOG.md +158 -0
- package/SKILLs.md +17 -0
- package/agent/index.js +32 -3
- package/ai/.claude-plugin/plugin.json +9 -0
- package/docs/GITHUB_COMMENTS.md +330 -0
- package/docs/GITHUB_COMMENTS_ANNOUNCEMENT.md +167 -0
- package/docs/QUICK-START-GITHUB-COMMENTS.md +84 -0
- package/docs/TEST-GITHUB-COMMENTS.md +129 -0
- package/docs/_scripts/generate-skills.js +149 -0
- package/docs/_scripts/link-replacer.js +164 -0
- package/docs/_scripts/upload-docs-to-openai.js +284 -0
- package/docs/claude-mcp-plugin.mdx +160 -0
- package/docs/docs.json +394 -0
- package/docs/github-integration-setup.md +266 -0
- package/docs/guide/best-practices-polling.mdx +154 -0
- package/docs/images/content/account/newprojectsettings.png +0 -0
- package/docs/images/content/account/projectpage.png +0 -0
- package/docs/images/content/account/projectreplays.png +0 -0
- package/docs/images/content/account/team-manage.png +0 -0
- package/docs/images/content/account/teampage.png +0 -0
- package/docs/images/content/extension/cursor.svg +1 -0
- package/docs/images/content/extension/vscode.svg +57 -0
- package/docs/images/content/extension/windsurf.svg +3 -0
- package/docs/images/content/self-hosted/launchtemplateid.png +0 -0
- package/docs/images/content/side-by-side.png +0 -0
- package/docs/images/content/vscode/ide-full.png +0 -0
- package/docs/images/content/vscode/running.png +0 -0
- package/docs/images/content/vscode/vscode-2-assert.png +0 -0
- package/docs/images/content/vscode/vscode-agent-preview.png +0 -0
- package/docs/images/content/vscode/vscode-copilot-ask.png +0 -0
- package/docs/images/content/vscode/vscode-file-creation.png +0 -0
- package/docs/images/content/vscode/vscode-install.png +0 -0
- package/docs/images/content/vscode/vscode-overview.png +0 -0
- package/docs/images/content/vscode/vscode-setup-walkthrough.png +0 -0
- package/docs/images/content/vscode/vscode-stopchat.png +0 -0
- package/docs/images/content/vscode/vscode-stoptest.png +0 -0
- package/docs/images/content/vscode/vscode-tdservice.png +0 -0
- package/docs/images/content/vscode/vscode-test-output.png +0 -0
- package/docs/images/content/vscode/vscode-testhistory.png +0 -0
- package/docs/images/content/vscode/vscode-testpane-runtests.png +0 -0
- package/docs/images/content/vscode/vscode-testpane.png +0 -0
- package/docs/images/template/dark.png +0 -0
- package/docs/images/template/icon.png +0 -0
- package/docs/images/template/light.png +0 -0
- package/docs/snippets/calendar-link.mdx +4 -0
- package/docs/snippets/gitignore-warning.mdx +7 -0
- package/docs/snippets/lifecycle-warning.mdx +6 -0
- package/docs/snippets/test-prereqs.mdx +12 -0
- package/docs/snippets/tests/assert-replay.mdx +7 -0
- package/docs/snippets/tests/assert-yaml.mdx +8 -0
- package/docs/snippets/tests/exec-js-replay.mdx +7 -0
- package/docs/snippets/tests/exec-js-yaml.mdx +32 -0
- package/docs/snippets/tests/exec-shell-replay.mdx +7 -0
- package/docs/snippets/tests/exec-shell-yaml.mdx +15 -0
- package/docs/snippets/tests/hover-image-replay.mdx +7 -0
- package/docs/snippets/tests/hover-image-yaml.mdx +17 -0
- package/docs/snippets/tests/hover-text-replay.mdx +7 -0
- package/docs/snippets/tests/hover-text-with-description-replay.mdx +7 -0
- package/docs/snippets/tests/hover-text-with-description-yaml.mdx +24 -0
- package/docs/snippets/tests/hover-text-yaml.mdx +14 -0
- package/docs/snippets/tests/match-image-replay.mdx +7 -0
- package/docs/snippets/tests/match-image-yaml.mdx +17 -0
- package/docs/snippets/tests/press-keys-replay.mdx +7 -0
- package/docs/snippets/tests/press-keys-yaml.mdx +36 -0
- package/docs/snippets/tests/remember-replay.mdx +7 -0
- package/docs/snippets/tests/remember-yaml.mdx +28 -0
- package/docs/snippets/tests/scroll-replay.mdx +7 -0
- package/docs/snippets/tests/scroll-until-image-replay.mdx +7 -0
- package/docs/snippets/tests/scroll-until-image-yaml.mdx +14 -0
- package/docs/snippets/tests/scroll-until-text-replay.mdx +7 -0
- package/docs/snippets/tests/scroll-until-text-yaml.mdx +17 -0
- package/docs/snippets/tests/scroll-yaml.mdx +30 -0
- package/docs/snippets/tests/type-repeated-replay.mdx +7 -0
- package/docs/snippets/tests/type-repeated-yaml.mdx +22 -0
- package/docs/snippets/tests/type-replay.mdx +7 -0
- package/docs/snippets/tests/type-yaml.mdx +28 -0
- package/docs/snippets/tests/wait-for-image-replay.mdx +7 -0
- package/docs/snippets/tests/wait-for-image-yaml.mdx +18 -0
- package/docs/snippets/tests/wait-for-text-replay.mdx +7 -0
- package/docs/snippets/tests/wait-for-text-yaml.mdx +18 -0
- package/docs/snippets/tests/wait-replay.mdx +7 -0
- package/docs/snippets/tests/wait-yaml.mdx +13 -0
- package/docs/styles.css +65 -0
- package/docs/v6/account/dashboard.mdx +16 -0
- package/docs/v6/account/enterprise.mdx +110 -0
- package/docs/v6/account/pricing.mdx +33 -0
- package/docs/v6/account/projects.mdx +33 -0
- package/docs/v6/account/team.mdx +35 -0
- package/docs/v6/action/ami.mdx +109 -0
- package/docs/v6/action/performance.mdx +105 -0
- package/docs/v6/action/secrets.mdx +93 -0
- package/docs/v6/apps/chrome-extensions.mdx +48 -0
- package/docs/v6/apps/desktop-apps.mdx +93 -0
- package/docs/v6/apps/mobile-apps.mdx +26 -0
- package/docs/v6/apps/static-websites.mdx +54 -0
- package/docs/v6/apps/tauri-apps.mdx +361 -0
- package/docs/v6/bugs/jira.mdx +232 -0
- package/docs/v6/cli/overview.mdx +66 -0
- package/docs/v6/commands/assert.mdx +45 -0
- package/docs/v6/commands/exec.mdx +282 -0
- package/docs/v6/commands/focus-application.mdx +44 -0
- package/docs/v6/commands/hover-image.mdx +69 -0
- package/docs/v6/commands/hover-text.mdx +47 -0
- package/docs/v6/commands/if.mdx +53 -0
- package/docs/v6/commands/match-image.mdx +67 -0
- package/docs/v6/commands/press-keys.mdx +87 -0
- package/docs/v6/commands/remember.mdx +49 -0
- package/docs/v6/commands/run.mdx +44 -0
- package/docs/v6/commands/scroll-until-image.mdx +66 -0
- package/docs/v6/commands/scroll-until-text.mdx +60 -0
- package/docs/v6/commands/scroll.mdx +69 -0
- package/docs/v6/commands/type.mdx +45 -0
- package/docs/v6/commands/wait-for-image.mdx +54 -0
- package/docs/v6/commands/wait-for-text.mdx +48 -0
- package/docs/v6/commands/wait.mdx +45 -0
- package/docs/v6/exporting/junit.mdx +218 -0
- package/docs/v6/exporting/playwright.mdx +197 -0
- package/docs/v6/features/auto-healing.mdx +144 -0
- package/docs/v6/features/generation.mdx +116 -0
- package/docs/v6/features/parallel-testing.mdx +151 -0
- package/docs/v6/features/reusable-snippets.mdx +131 -0
- package/docs/v6/features/selectorless.mdx +80 -0
- package/docs/v6/features/visual-assertions.mdx +139 -0
- package/docs/v6/getting-started/ci.mdx +146 -0
- package/docs/v6/getting-started/cli.mdx +91 -0
- package/docs/v6/getting-started/editing.mdx +100 -0
- package/docs/v6/getting-started/playwright.mdx +342 -0
- package/docs/v6/getting-started/running.mdx +48 -0
- package/docs/v6/getting-started/self-hosting.mdx +408 -0
- package/docs/v6/getting-started/vscode.mdx +88 -0
- package/docs/v6/guide/assertions.mdx +189 -0
- package/docs/v6/guide/authentication.mdx +136 -0
- package/docs/v6/guide/code.mdx +65 -0
- package/docs/v6/guide/dashcam.mdx +118 -0
- package/docs/v6/guide/environment-variables.mdx +26 -0
- package/docs/v6/guide/lifecycle.mdx +242 -0
- package/docs/v6/guide/locating.mdx +141 -0
- package/docs/v6/guide/protips.mdx +43 -0
- package/docs/v6/guide/variables.mdx +143 -0
- package/docs/v6/guide/waiting.mdx +130 -0
- package/docs/v6/importing/csv.mdx +196 -0
- package/docs/v6/importing/gherkin.mdx +143 -0
- package/docs/v6/importing/jira.mdx +164 -0
- package/docs/v6/importing/testrail.mdx +162 -0
- package/docs/v6/integrations/electron.mdx +146 -0
- package/docs/v6/integrations/netlify.mdx +100 -0
- package/docs/v6/integrations/vercel.mdx +125 -0
- package/docs/v6/interactive/explore.mdx +99 -0
- package/docs/v6/interactive/run.mdx +52 -0
- package/docs/v6/interactive/save.mdx +63 -0
- package/docs/v6/overview/comparison.mdx +101 -0
- package/docs/v6/overview/faq.mdx +162 -0
- package/docs/v6/overview/performance.mdx +52 -0
- package/docs/v6/overview/quickstart.mdx +137 -0
- package/docs/v6/overview/what-is-testdriver.mdx +85 -0
- package/docs/v6/scenarios/ai-chatbot.mdx +28 -0
- package/docs/v6/scenarios/cookie-banner.mdx +32 -0
- package/docs/v6/scenarios/file-upload.mdx +33 -0
- package/docs/v6/scenarios/form-filling.mdx +32 -0
- package/docs/v6/scenarios/log-in.mdx +75 -0
- package/docs/v6/scenarios/pdf-generation.mdx +25 -0
- package/docs/v6/scenarios/spell-check.mdx +22 -0
- package/docs/v6/security/action.mdx +84 -0
- package/docs/v6/security/agent.mdx +73 -0
- package/docs/v6/security/platform.mdx +77 -0
- package/docs/v6/tutorials/advanced-test.mdx +81 -0
- package/docs/v6/tutorials/basic-test.mdx +45 -0
- package/docs/v7/_drafts/agents.mdx +852 -0
- package/docs/v7/_drafts/architecture.mdx +399 -0
- package/docs/v7/_drafts/auto-cache-key.mdx +167 -0
- package/docs/v7/_drafts/awesome-logs-quick-ref.mdx +100 -0
- package/docs/v7/_drafts/best-practices.mdx +486 -0
- package/docs/v7/_drafts/caching-ai.mdx +215 -0
- package/docs/v7/_drafts/caching-selectors.mdx +424 -0
- package/docs/v7/_drafts/caching.mdx +366 -0
- package/docs/v7/_drafts/cli-to-sdk-migration.mdx +425 -0
- package/docs/v7/_drafts/commands/assert.mdx +45 -0
- package/docs/v7/_drafts/commands/exec.mdx +282 -0
- package/docs/v7/_drafts/commands/focus-application.mdx +44 -0
- package/docs/v7/_drafts/commands/hover-image.mdx +69 -0
- package/docs/v7/_drafts/commands/hover-text.mdx +47 -0
- package/docs/v7/_drafts/commands/if.mdx +53 -0
- package/docs/v7/_drafts/commands/match-image.mdx +67 -0
- package/docs/v7/_drafts/commands/press-keys.mdx +87 -0
- package/docs/v7/_drafts/commands/remember.mdx +49 -0
- package/docs/v7/_drafts/commands/run.mdx +44 -0
- package/docs/v7/_drafts/commands/scroll-until-image.mdx +66 -0
- package/docs/v7/_drafts/commands/scroll-until-text.mdx +60 -0
- package/docs/v7/_drafts/commands/scroll.mdx +69 -0
- package/docs/v7/_drafts/commands/type.mdx +45 -0
- package/docs/v7/_drafts/commands/wait-for-image.mdx +54 -0
- package/docs/v7/_drafts/commands/wait-for-text.mdx +48 -0
- package/docs/v7/_drafts/commands/wait.mdx +45 -0
- package/docs/v7/_drafts/configuration.mdx +378 -0
- package/docs/v7/_drafts/contributing.mdx +174 -0
- package/docs/v7/_drafts/core.mdx +458 -0
- package/docs/v7/_drafts/dashcam-title-feature.mdx +89 -0
- package/docs/v7/_drafts/debugging.mdx +349 -0
- package/docs/v7/_drafts/error-handling.mdx +501 -0
- package/docs/v7/_drafts/faq.mdx +393 -0
- package/docs/v7/_drafts/hooks.mdx +360 -0
- package/docs/v7/_drafts/init-command.mdx +95 -0
- package/docs/v7/_drafts/installation.mdx +420 -0
- package/docs/v7/_drafts/migration.mdx +562 -0
- package/docs/v7/_drafts/observable.mdx +604 -0
- package/docs/v7/_drafts/playwright.mdx +342 -0
- package/docs/v7/_drafts/plugin-migration.mdx +220 -0
- package/docs/v7/_drafts/powerful.mdx +419 -0
- package/docs/v7/_drafts/presets.mdx +210 -0
- package/docs/v7/_drafts/progressive-disclosure.mdx +230 -0
- package/docs/v7/_drafts/prompt-cache.mdx +200 -0
- package/docs/v7/_drafts/provision.mdx +390 -0
- package/docs/v7/_drafts/quick-start-test-recording.mdx +214 -0
- package/docs/v7/_drafts/readme.mdx +135 -0
- package/docs/v7/_drafts/reports.mdx +414 -0
- package/docs/v7/_drafts/scalable.mdx +754 -0
- package/docs/v7/_drafts/screenshot.mdx +155 -0
- package/docs/v7/_drafts/sdk-awesome-logs.mdx +468 -0
- package/docs/v7/_drafts/sdk-browser-rendering.mdx +167 -0
- package/docs/v7/_drafts/sdk-migration.mdx +474 -0
- package/docs/v7/_drafts/sdk-v7-complete.mdx +345 -0
- package/docs/v7/_drafts/self-hosting.mdx +369 -0
- package/docs/v7/_drafts/test-recording.mdx +382 -0
- package/docs/v7/_drafts/troubleshooting.mdx +526 -0
- package/docs/v7/_drafts/vitest-plugin.mdx +477 -0
- package/docs/v7/_drafts/vitest.mdx +535 -0
- package/docs/v7/_drafts/writing-tests.mdx +25 -0
- package/{ai/skills/testdriver:ai/SKILL.md → docs/v7/ai.mdx} +4 -3
- package/{ai/skills/testdriver:assert/SKILL.md → docs/v7/assert.mdx} +4 -3
- package/{ai/skills/testdriver:aws-setup/SKILL.md → docs/v7/aws-setup.mdx} +4 -3
- package/{ai/skills/testdriver:caching/SKILL.md → docs/v7/caching.mdx} +7 -3
- package/{ai/skills/testdriver:captcha/SKILL.md → docs/v7/captcha.mdx} +4 -3
- package/{ai/skills/testdriver:ci-cd/SKILL.md → docs/v7/ci-cd.mdx} +4 -3
- package/{ai/skills/testdriver:click/SKILL.md → docs/v7/click.mdx} +4 -3
- package/{ai/skills/testdriver:client/SKILL.md → docs/v7/client.mdx} +8 -3
- package/{ai/skills/testdriver:cloud/SKILL.md → docs/v7/cloud.mdx} +4 -3
- package/{ai/skills/testdriver:customizing-devices/SKILL.md → docs/v7/customizing-devices.mdx} +3 -3
- package/{ai/skills/testdriver:dashcam/SKILL.md → docs/v7/dashcam.mdx} +4 -3
- package/docs/v7/debugging-with-screenshots.mdx +402 -0
- package/{ai/skills/testdriver:device-config/SKILL.md → docs/v7/device-config.mdx} +3 -3
- package/{ai/skills/testdriver:double-click/SKILL.md → docs/v7/double-click.mdx} +3 -3
- package/{ai/skills/testdriver:elements/SKILL.md → docs/v7/elements.mdx} +4 -3
- package/{ai/skills/testdriver:enterprise/SKILL.md → docs/v7/enterprise.mdx} +5 -3
- package/docs/v7/examples.mdx +5 -0
- package/{ai/skills/testdriver:exec/SKILL.md → docs/v7/exec.mdx} +4 -3
- package/{ai/skills/testdriver:find/SKILL.md → docs/v7/find.mdx} +4 -3
- package/{ai/skills/testdriver:focus-application/SKILL.md → docs/v7/focus-application.mdx} +4 -3
- package/{ai/skills/testdriver:generating-tests/SKILL.md → docs/v7/generating-tests.mdx} +3 -3
- package/{ai/skills/testdriver:hover/SKILL.md → docs/v7/hover.mdx} +4 -3
- package/{ai/skills/testdriver:locating-elements/SKILL.md → docs/v7/locating-elements.mdx} +3 -3
- package/{ai/skills/testdriver:making-assertions/SKILL.md → docs/v7/making-assertions.mdx} +3 -3
- package/{ai/skills/testdriver:mouse-down/SKILL.md → docs/v7/mouse-down.mdx} +3 -3
- package/{ai/skills/testdriver:mouse-up/SKILL.md → docs/v7/mouse-up.mdx} +3 -3
- package/docs/v7/ocr.mdx +236 -0
- package/{ai/skills/testdriver:performing-actions/SKILL.md → docs/v7/performing-actions.mdx} +3 -3
- package/{ai/skills/testdriver:press-keys/SKILL.md → docs/v7/press-keys.mdx} +4 -3
- package/{ai/skills/testdriver:quickstart/SKILL.md → docs/v7/quickstart.mdx} +6 -20
- package/{ai/skills/testdriver:reusable-code/SKILL.md → docs/v7/reusable-code.mdx} +3 -3
- package/{ai/skills/testdriver:right-click/SKILL.md → docs/v7/right-click.mdx} +3 -3
- package/{ai/skills/testdriver:running-tests/SKILL.md → docs/v7/running-tests.mdx} +7 -3
- package/{ai/skills/testdriver:screenshot/SKILL.md → docs/v7/screenshot.mdx} +88 -6
- package/{ai/skills/testdriver:scroll/SKILL.md → docs/v7/scroll.mdx} +40 -3
- package/{ai/skills/testdriver:secrets/SKILL.md → docs/v7/secrets.mdx} +3 -3
- package/{ai/skills/testdriver:self-hosted/SKILL.md → docs/v7/self-hosted.mdx} +4 -3
- package/{ai/skills/testdriver:type/SKILL.md → docs/v7/type.mdx} +4 -3
- package/{ai/skills/testdriver:variables/SKILL.md → docs/v7/variables.mdx} +3 -3
- package/{ai/skills/testdriver:waiting-for-elements/SKILL.md → docs/v7/waiting-for-elements.mdx} +3 -3
- package/{ai/skills/testdriver:what-is-testdriver/SKILL.md → docs/v7/what-is-testdriver.mdx} +3 -3
- package/eslint.config.js +67 -0
- package/examples/ai.test.mjs +30 -0
- package/examples/assert.test.mjs +47 -0
- package/examples/captcha-api.test.mjs +50 -0
- package/examples/chrome-extension.test.mjs +94 -0
- package/examples/drag-and-drop.test.mjs +58 -0
- package/examples/element-not-found.test.mjs +26 -0
- package/examples/exec-output.test.mjs +59 -0
- package/examples/exec-pwsh.test.mjs +57 -0
- package/examples/focus-window.test.mjs +36 -0
- package/examples/formatted-logging.test.mjs +26 -0
- package/examples/hover-image.test.mjs +52 -0
- package/examples/hover-text-with-description.test.mjs +56 -0
- package/examples/hover-text.test.mjs +27 -0
- package/examples/installer.test.mjs +49 -0
- package/examples/launch-vscode-linux.test.mjs +54 -0
- package/examples/match-image.test.mjs +54 -0
- package/examples/no-provision.test.mjs +23 -0
- package/examples/press-keys.test.mjs +50 -0
- package/examples/prompt.test.mjs +33 -0
- package/examples/scroll-keyboard.test.mjs +37 -0
- package/examples/scroll-until-image.test.mjs +39 -0
- package/examples/scroll-until-text.test.mjs +67 -0
- package/examples/scroll.test.mjs +41 -0
- package/examples/type.test.mjs +45 -0
- package/examples/windows-installer.test.mjs +53 -0
- package/jsconfig.json +26 -0
- package/lib/vitest/hooks.mjs +3 -0
- package/manual/test-init-command.js +223 -0
- package/mcp-server/README.md +312 -0
- package/mcp-server/mcp-app.html +28 -0
- package/mcp-server/mcp-config.example.json +19 -0
- package/mcp-server/package-lock.json +4018 -0
- package/mcp-server/package.json +29 -0
- package/mcp-server/src/codegen.ts +189 -0
- package/mcp-server/src/mcp-app.css +360 -0
- package/mcp-server/src/mcp-app.ts +547 -0
- package/mcp-server/src/provision-types.ts +209 -0
- package/mcp-server/src/server.ts +2313 -0
- package/mcp-server/src/session.ts +194 -0
- package/mcp-server/tsconfig.json +16 -0
- package/mcp-server/vite.config.ts +23 -0
- package/package.json +2 -17
- package/scripts/generate-skills.js +94 -0
- package/sdk.js +3 -0
- package/setup/aws/cloudformation.yaml +470 -0
- package/setup/aws/spawn-runner.sh +190 -0
- package/test/api-resilience.test.mjs +0 -0
- package/test/captcha-solver.test.mjs +152 -0
- package/test/chrome-remote-debugging.test.mjs +66 -0
- package/test/duckduckgo/experiment.test.mjs +28 -0
- package/test/duckduckgo/setup.test.mjs +29 -0
- package/test/manual/debug-locate-response.js +82 -0
- package/test/manual/reconnect-provision.test.mjs +49 -0
- package/test/manual/test-console-logs.test.mjs +42 -0
- package/test/manual/test-find-api.js +73 -0
- package/test/manual/test-init.sh +54 -0
- package/test/manual/test-prompt-cache.js +97 -0
- package/test/manual/test-provision-auth.mjs +22 -0
- package/test/manual/test-sandbox-render.js +29 -0
- package/test/manual/test-sdk-methods.js +15 -0
- package/test/manual/test-sdk-refactor.js +53 -0
- package/test/manual/test-stack-trace.mjs +57 -0
- package/test/manual/verify-element-api.js +89 -0
- package/test/manual/verify-types.js +0 -0
- package/test/manual-unawaited-promise.test.mjs +31 -0
- package/test-ide-preview.mjs +17 -0
- package/tests/airbnb-booking.test.mjs +39 -0
- package/tests/airbnb-search.test.mjs +43 -0
- package/tests/example.test.js +33 -0
- package/tests/login.js +28 -0
- package/vitest.config.mjs +24 -0
- package/vscode-extension/.vscodeignore +12 -0
- package/vscode-extension/README.md +94 -0
- package/vscode-extension/media/icon.png +0 -0
- package/vscode-extension/package-lock.json +4126 -0
- package/vscode-extension/package.json +86 -0
- package/vscode-extension/src/extension.ts +829 -0
- package/vscode-extension/testdriverai-0.1.0.vsix +0 -0
- package/vscode-extension/tsconfig.json +16 -0
- package/ai/skills/testdriver:examples/SKILL.md +0 -7
- package/ai/skills/testdriver:mcp-workflow/SKILL.md +0 -410
- package/ai/skills/testdriver:testdriver/SKILL.md +0 -523
|
@@ -0,0 +1,167 @@
|
|
|
1
|
+
# 🎉 GitHub Comments Feature
|
|
2
|
+
|
|
3
|
+
## What's New
|
|
4
|
+
|
|
5
|
+
TestDriver now automatically posts beautiful, detailed comments to your GitHub pull requests and commits with:
|
|
6
|
+
|
|
7
|
+
- ✅ **Test Results** - Pass/fail statistics at a glance
|
|
8
|
+
- 🎥 **Dashcam GIF Replays** - Embedded animated previews of each test
|
|
9
|
+
- 📊 **Detailed Statistics** - Duration, platform, branch, commit info
|
|
10
|
+
- ❌ **Exception Details** - Full error messages and stack traces for failures
|
|
11
|
+
- 🔄 **Smart Updates** - Updates existing comments instead of creating duplicates
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
### 1. Add to GitHub Actions
|
|
16
|
+
|
|
17
|
+
```yaml
|
|
18
|
+
- name: Run TestDriver tests
|
|
19
|
+
env:
|
|
20
|
+
TD_API_KEY: ${{ secrets.TD_API_KEY }}
|
|
21
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
22
|
+
GITHUB_PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
23
|
+
run: npm run test:sdk
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
### 2. That's it!
|
|
27
|
+
|
|
28
|
+
TestDriver will automatically detect the CI environment and post comments when:
|
|
29
|
+
- `GITHUB_TOKEN` is present
|
|
30
|
+
- `GITHUB_PR_NUMBER` (for PR comments) or `GITHUB_SHA` (for commit comments) is set
|
|
31
|
+
|
|
32
|
+
## Example Comment
|
|
33
|
+
|
|
34
|
+

|
|
35
|
+
|
|
36
|
+
Your team will see:
|
|
37
|
+
- **Status badges** with pass/fail counts
|
|
38
|
+
- **Embedded GIF replays** directly in the comment
|
|
39
|
+
- **Clickable links** to full test runs and individual replays
|
|
40
|
+
- **Collapsible error details** with full stack traces
|
|
41
|
+
|
|
42
|
+
## Features
|
|
43
|
+
|
|
44
|
+
### 🎥 Dashcam Replays
|
|
45
|
+
|
|
46
|
+
Every test automatically records a dashcam replay. These appear in the GitHub comment as:
|
|
47
|
+
1. **GIF preview** - Shows the test execution as an animated image
|
|
48
|
+
2. **Link to full replay** - Opens the complete replay in TestDriver console
|
|
49
|
+
3. **Test-specific context** - Each test has its own replay section
|
|
50
|
+
|
|
51
|
+
### 📊 Test Statistics
|
|
52
|
+
|
|
53
|
+
The comment shows:
|
|
54
|
+
- Total test count
|
|
55
|
+
- Pass/fail/skip breakdown
|
|
56
|
+
- Total execution time
|
|
57
|
+
- Platform (Linux/Windows/Mac)
|
|
58
|
+
- Git branch and commit
|
|
59
|
+
|
|
60
|
+
### ❌ Exception Handling
|
|
61
|
+
|
|
62
|
+
Failed tests include:
|
|
63
|
+
- Error message prominently displayed
|
|
64
|
+
- Collapsible stack trace
|
|
65
|
+
- Direct link to the failing test's replay
|
|
66
|
+
- File and line number information
|
|
67
|
+
|
|
68
|
+
### 🔄 Comment Updates
|
|
69
|
+
|
|
70
|
+
TestDriver intelligently:
|
|
71
|
+
- **Updates existing comments** on subsequent pushes to the same PR
|
|
72
|
+
- **Creates new comments** only when needed
|
|
73
|
+
- **Identifies its own comments** using a signature
|
|
74
|
+
|
|
75
|
+
## Configuration
|
|
76
|
+
|
|
77
|
+
### Environment Variables
|
|
78
|
+
|
|
79
|
+
| Variable | Description | Required |
|
|
80
|
+
|----------|-------------|----------|
|
|
81
|
+
| `TD_API_KEY` | TestDriver API key | ✅ Yes |
|
|
82
|
+
| `GITHUB_TOKEN` | GitHub token | ✅ Yes |
|
|
83
|
+
| `GITHUB_PR_NUMBER` | PR number for PR comments | 📝 Recommended |
|
|
84
|
+
| `GITHUB_SHA` | Commit SHA (fallback) | ⚙️ Auto-detected |
|
|
85
|
+
| `TESTDRIVER_SKIP_GITHUB_COMMENT` | Set to 'true' to disable | ❌ No |
|
|
86
|
+
|
|
87
|
+
### Disabling Comments
|
|
88
|
+
|
|
89
|
+
To disable GitHub comments for a specific run:
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
TESTDRIVER_SKIP_GITHUB_COMMENT=true npm run test
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
## Documentation
|
|
96
|
+
|
|
97
|
+
For complete documentation, see:
|
|
98
|
+
- **[GitHub Comments Guide](./GITHUB_COMMENTS.md)** - Full setup and configuration
|
|
99
|
+
- **[Example Workflow](./../examples/github-actions.yml)** - Copy-paste GitHub Actions workflow
|
|
100
|
+
- **[Example Test](./../examples/github-comment-demo.test.mjs)** - Demo test file
|
|
101
|
+
|
|
102
|
+
## Troubleshooting
|
|
103
|
+
|
|
104
|
+
### Comment not appearing?
|
|
105
|
+
|
|
106
|
+
1. **Check environment variables:**
|
|
107
|
+
```bash
|
|
108
|
+
echo "Token: ${GITHUB_TOKEN:0:10}..."
|
|
109
|
+
echo "PR: $GITHUB_PR_NUMBER"
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
2. **Verify permissions:**
|
|
113
|
+
- GitHub Actions needs `pull-requests: write` or `contents: write`
|
|
114
|
+
|
|
115
|
+
3. **Check logs:**
|
|
116
|
+
- Look for "Posting GitHub comment..." in test output
|
|
117
|
+
- Check for "GitHub token not found" warnings
|
|
118
|
+
|
|
119
|
+
### Replays not embedded?
|
|
120
|
+
|
|
121
|
+
- Ensure tests are using `await testdriver.provision.*()`
|
|
122
|
+
- Check that dashcam stops successfully (look for "🎥 Dashcam URL")
|
|
123
|
+
- Verify replay URLs in test output
|
|
124
|
+
|
|
125
|
+
## Examples
|
|
126
|
+
|
|
127
|
+
### Basic Test with Comment
|
|
128
|
+
|
|
129
|
+
```javascript
|
|
130
|
+
it("should login successfully", async (context) => {
|
|
131
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
132
|
+
|
|
133
|
+
await testdriver.provision.chrome({
|
|
134
|
+
url: 'https://your-app.com/login',
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Test steps...
|
|
138
|
+
const result = await testdriver.assert("I'm logged in");
|
|
139
|
+
expect(result).toBeTruthy();
|
|
140
|
+
|
|
141
|
+
// Dashcam automatically recorded and will appear in GitHub comment!
|
|
142
|
+
});
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
### Local Testing
|
|
146
|
+
|
|
147
|
+
Run locally without posting comments:
|
|
148
|
+
|
|
149
|
+
```bash
|
|
150
|
+
npm run test:sdk
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
Run locally WITH comment posting (requires token):
|
|
154
|
+
|
|
155
|
+
```bash
|
|
156
|
+
GITHUB_TOKEN=ghp_xxx GITHUB_PR_NUMBER=123 npm run test:sdk
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## Support
|
|
160
|
+
|
|
161
|
+
- **Documentation:** [testdriver.ai/docs](https://testdriver.ai/docs)
|
|
162
|
+
- **Issues:** [GitHub Issues](https://github.com/testdriverai/testdriverai/issues)
|
|
163
|
+
- **Discord:** [Join our community](https://discord.gg/testdriver)
|
|
164
|
+
|
|
165
|
+
---
|
|
166
|
+
|
|
167
|
+
Made with ❤️ by the TestDriver team
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# Quick Start: GitHub Comments
|
|
2
|
+
|
|
3
|
+
## For GitHub Actions (Easiest!)
|
|
4
|
+
|
|
5
|
+
Add this to your `.github/workflows/test.yml`:
|
|
6
|
+
|
|
7
|
+
```yaml
|
|
8
|
+
name: Tests
|
|
9
|
+
|
|
10
|
+
on: pull_request
|
|
11
|
+
|
|
12
|
+
jobs:
|
|
13
|
+
test:
|
|
14
|
+
runs-on: ubuntu-latest
|
|
15
|
+
permissions:
|
|
16
|
+
contents: read
|
|
17
|
+
pull-requests: write # ← This is all you need!
|
|
18
|
+
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
|
|
22
|
+
- name: Setup Node
|
|
23
|
+
uses: actions/setup-node@v4
|
|
24
|
+
with:
|
|
25
|
+
node-version: '20'
|
|
26
|
+
|
|
27
|
+
- run: npm ci
|
|
28
|
+
|
|
29
|
+
- name: Run TestDriver tests
|
|
30
|
+
env:
|
|
31
|
+
TD_API_KEY: ${{ secrets.TD_API_KEY }}
|
|
32
|
+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Auto-provided
|
|
33
|
+
run: vitest run
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
That's it! TestDriver will automatically:
|
|
37
|
+
- ✅ Detect the PR number
|
|
38
|
+
- ✅ Detect the repository
|
|
39
|
+
- ✅ Post beautiful comments with test results
|
|
40
|
+
- 🎥 Embed dashcam GIF replays
|
|
41
|
+
- 📊 Show pass/fail statistics
|
|
42
|
+
- 🔴 Display exception details
|
|
43
|
+
|
|
44
|
+
## For Local Development
|
|
45
|
+
|
|
46
|
+
1. **Create a GitHub Personal Access Token**
|
|
47
|
+
- Go to https://github.com/settings/tokens
|
|
48
|
+
- Click "Generate new token (classic)"
|
|
49
|
+
- Select scope: `repo` or `public_repo`
|
|
50
|
+
- Copy the token
|
|
51
|
+
|
|
52
|
+
2. **Set environment variables**
|
|
53
|
+
```bash
|
|
54
|
+
export GITHUB_TOKEN=ghp_your_token_here
|
|
55
|
+
export GITHUB_PR_NUMBER=123
|
|
56
|
+
vitest run
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
## What Gets Posted
|
|
60
|
+
|
|
61
|
+
```markdown
|
|
62
|
+
# 🟢 TestDriver Test Results
|
|
63
|
+
|
|
64
|
+
**Status:** ✅ PASSED
|
|
65
|
+
**Duration:** 12.3s
|
|
66
|
+
|
|
67
|
+
## 📝 Test Results
|
|
68
|
+
| Status | Test | Duration | Replay |
|
|
69
|
+
|--------|------|----------|--------|
|
|
70
|
+
| ✅ | Login test | 4.5s | [🎥 View](link) |
|
|
71
|
+
|
|
72
|
+
## 🎥 Dashcam Replays
|
|
73
|
+
[Animated GIF embedded here]
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Disable Comments
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
TESTDRIVER_SKIP_GITHUB_COMMENT=true vitest run
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Full Documentation
|
|
83
|
+
|
|
84
|
+
See [github-integration-setup.md](./github-integration-setup.md) for complete details.
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
# Testing GitHub Comments Feature
|
|
2
|
+
|
|
3
|
+
## Quick Test Instructions
|
|
4
|
+
|
|
5
|
+
1. **Ensure TD_API_KEY is set**
|
|
6
|
+
- Go to: https://github.com/testdriverai/testdriverai/settings/secrets/actions
|
|
7
|
+
- Add secret named `TD_API_KEY` with your API key from https://console.testdriver.ai/team
|
|
8
|
+
- If already set, you're good to go!
|
|
9
|
+
|
|
10
|
+
2. **Create a test branch and PR**
|
|
11
|
+
```bash
|
|
12
|
+
cd /Users/ianjennings/Development/testdriverai
|
|
13
|
+
git checkout -b test-github-comments
|
|
14
|
+
|
|
15
|
+
# Make a small change to trigger the workflow
|
|
16
|
+
echo "# Test GitHub Comments" >> test-comment.md
|
|
17
|
+
git add test-comment.md
|
|
18
|
+
git commit -m "test: trigger GitHub comment workflow"
|
|
19
|
+
git push origin test-github-comments
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
3. **Create Pull Request**
|
|
23
|
+
```bash
|
|
24
|
+
gh pr create --title "Test: GitHub Comments Feature" \
|
|
25
|
+
--body "Testing automatic GitHub comments with test results and dashcam replays"
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
Or create via web: https://github.com/testdriverai/testdriverai/compare
|
|
29
|
+
|
|
30
|
+
4. **Watch the Magic Happen! ✨**
|
|
31
|
+
- The workflow will automatically run: `.github/workflows/test-with-comments.yml`
|
|
32
|
+
- View progress at: https://github.com/testdriverai/testdriverai/actions
|
|
33
|
+
- After ~30-60 seconds, you'll see a comment on your PR with:
|
|
34
|
+
- ✅ Test results summary
|
|
35
|
+
- 🎥 Embedded dashcam GIF replay
|
|
36
|
+
- 📊 Test statistics
|
|
37
|
+
- 📋 Link to full test run
|
|
38
|
+
|
|
39
|
+
## What the Test Does
|
|
40
|
+
|
|
41
|
+
The workflow runs `examples/assert.test.mjs` which:
|
|
42
|
+
- Provisions a Chrome browser
|
|
43
|
+
- Navigates to https://saucedemo.com
|
|
44
|
+
- Performs login actions
|
|
45
|
+
- Uses TestDriver's `assert()` to verify elements
|
|
46
|
+
- Records a dashcam replay of the entire test
|
|
47
|
+
- Posts results to your PR automatically
|
|
48
|
+
|
|
49
|
+
## Expected Comment Output
|
|
50
|
+
|
|
51
|
+
You should see a comment like:
|
|
52
|
+
|
|
53
|
+
```markdown
|
|
54
|
+
# 🟢 TestDriver Test Results
|
|
55
|
+
|
|
56
|
+
**Status:** ✅ PASSED
|
|
57
|
+
**Duration:** 25.3s
|
|
58
|
+
**Platform:** linux
|
|
59
|
+
**Branch:** `test-github-comments`
|
|
60
|
+
**Commit:** `abc1234`
|
|
61
|
+
|
|
62
|
+
## 📊 Test Summary
|
|
63
|
+
|
|
64
|
+
Total: 1
|
|
65
|
+
Passed: 1 ✅
|
|
66
|
+
Failed: 0 ❌
|
|
67
|
+
Skipped: 0 ⏭️
|
|
68
|
+
|
|
69
|
+
### [📋 View Full Test Run](https://console.testdriver.ai/runs/...)
|
|
70
|
+
|
|
71
|
+
## 📝 Test Results
|
|
72
|
+
|
|
73
|
+
| Status | Test | File | Duration | Replay |
|
|
74
|
+
|--------|------|------|----------|--------|
|
|
75
|
+
| ✅ | Assert Test | `examples/assert.test.mjs` | 25.3s | [🎥 View](https://console.testdriver.ai/replay/...) |
|
|
76
|
+
|
|
77
|
+
## 🎥 Dashcam Replays
|
|
78
|
+
|
|
79
|
+
### Assert Test
|
|
80
|
+
|
|
81
|
+
[](https://console.testdriver.ai/replay/...)
|
|
82
|
+
|
|
83
|
+
[🎬 View Full Replay](https://console.testdriver.ai/replay/...)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
## Troubleshooting
|
|
87
|
+
|
|
88
|
+
### No comment appears
|
|
89
|
+
- Check Actions tab for errors: https://github.com/testdriverai/testdriverai/actions
|
|
90
|
+
- Verify `TD_API_KEY` secret is set correctly
|
|
91
|
+
- Ensure workflow has `pull-requests: write` permission (it does in the provided workflow)
|
|
92
|
+
|
|
93
|
+
### Workflow doesn't run
|
|
94
|
+
- Make sure the workflow file is on the branch you're testing
|
|
95
|
+
- Check that PR is from the same repository (not a fork)
|
|
96
|
+
|
|
97
|
+
### Test fails
|
|
98
|
+
- View the workflow logs for details
|
|
99
|
+
- Check TestDriver API status
|
|
100
|
+
- Verify your API key is valid
|
|
101
|
+
|
|
102
|
+
## Manual Trigger
|
|
103
|
+
|
|
104
|
+
You can also trigger the workflow manually:
|
|
105
|
+
1. Go to: https://github.com/testdriverai/testdriverai/actions/workflows/test-with-comments.yml
|
|
106
|
+
2. Click "Run workflow"
|
|
107
|
+
3. Select your branch
|
|
108
|
+
4. Click "Run workflow"
|
|
109
|
+
|
|
110
|
+
Note: Manual triggers won't post PR comments (no PR context), but will still run tests.
|
|
111
|
+
|
|
112
|
+
## Clean Up
|
|
113
|
+
|
|
114
|
+
After testing, delete the test branch:
|
|
115
|
+
```bash
|
|
116
|
+
gh pr close YOUR_PR_NUMBER
|
|
117
|
+
git checkout main
|
|
118
|
+
git branch -D test-github-comments
|
|
119
|
+
git push origin --delete test-github-comments
|
|
120
|
+
rm test-comment.md # if it exists on main
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
## Next Steps
|
|
124
|
+
|
|
125
|
+
Once you've confirmed it works:
|
|
126
|
+
1. Customize the workflow for your needs
|
|
127
|
+
2. Add more test files to the run command
|
|
128
|
+
3. Set up for all PRs in your repository
|
|
129
|
+
4. Share with your team!
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Script to generate MCP skills from docs/v7/*.mdx files
|
|
8
|
+
*
|
|
9
|
+
* This script reads the frontmatter from each mdx file and generates
|
|
10
|
+
* SKILL.md files in the skills/ output directory.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const DOCS_DIR = path.join(__dirname, "../v7");
|
|
14
|
+
const OUTPUT_DIR = path.join(__dirname, "../../skills");
|
|
15
|
+
|
|
16
|
+
// Parse YAML frontmatter from mdx content
|
|
17
|
+
function parseFrontmatter(content) {
|
|
18
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---/);
|
|
19
|
+
if (!frontmatterMatch) {
|
|
20
|
+
return { frontmatter: {}, body: content };
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const frontmatterText = frontmatterMatch[1];
|
|
24
|
+
const body = content.slice(frontmatterMatch[0].length).trim();
|
|
25
|
+
|
|
26
|
+
// Simple YAML parser for our use case
|
|
27
|
+
const frontmatter = {};
|
|
28
|
+
const lines = frontmatterText.split("\n");
|
|
29
|
+
for (const line of lines) {
|
|
30
|
+
const match = line.match(/^(\w+):\s*"?([^"]*)"?\s*$/);
|
|
31
|
+
if (match) {
|
|
32
|
+
frontmatter[match[1]] = match[2];
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return { frontmatter, body };
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// Get skill name from filename
|
|
40
|
+
function getSkillName(filename) {
|
|
41
|
+
return `testdriver:${filename.replace(".mdx", "")}`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
// Generate SKILL.md content
|
|
45
|
+
function generateSkillContent(filename, frontmatter, body) {
|
|
46
|
+
const skillName = getSkillName(filename);
|
|
47
|
+
const description = frontmatter.description || frontmatter.sidebarTitle || filename.replace(".mdx", "");
|
|
48
|
+
|
|
49
|
+
return `---
|
|
50
|
+
name: ${skillName}
|
|
51
|
+
description: ${description}
|
|
52
|
+
---
|
|
53
|
+
<!-- Generated from ${filename}. DO NOT EDIT. -->
|
|
54
|
+
|
|
55
|
+
${body}
|
|
56
|
+
`;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Process all mdx files
|
|
60
|
+
function processFiles() {
|
|
61
|
+
// Ensure output directory exists
|
|
62
|
+
if (!fs.existsSync(OUTPUT_DIR)) {
|
|
63
|
+
fs.mkdirSync(OUTPUT_DIR, { recursive: true });
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
const files = fs.readdirSync(DOCS_DIR);
|
|
67
|
+
const mdxFiles = files.filter(
|
|
68
|
+
(file) => file.endsWith(".mdx") && !file.startsWith("_")
|
|
69
|
+
);
|
|
70
|
+
|
|
71
|
+
console.log(`Found ${mdxFiles.length} mdx files to process\n`);
|
|
72
|
+
|
|
73
|
+
let generated = 0;
|
|
74
|
+
let errors = 0;
|
|
75
|
+
|
|
76
|
+
for (const file of mdxFiles) {
|
|
77
|
+
const filePath = path.join(DOCS_DIR, file);
|
|
78
|
+
const skillName = getSkillName(file);
|
|
79
|
+
const outputDir = path.join(OUTPUT_DIR, skillName);
|
|
80
|
+
const outputPath = path.join(outputDir, "SKILL.md");
|
|
81
|
+
|
|
82
|
+
try {
|
|
83
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
84
|
+
const { frontmatter, body } = parseFrontmatter(content);
|
|
85
|
+
const skillContent = generateSkillContent(file, frontmatter, body);
|
|
86
|
+
|
|
87
|
+
// Create skill directory
|
|
88
|
+
if (!fs.existsSync(outputDir)) {
|
|
89
|
+
fs.mkdirSync(outputDir, { recursive: true });
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
fs.writeFileSync(outputPath, skillContent, "utf-8");
|
|
93
|
+
console.log(`✅ ${skillName}`);
|
|
94
|
+
generated++;
|
|
95
|
+
} catch (error) {
|
|
96
|
+
console.error(`❌ ${file}: ${error.message}`);
|
|
97
|
+
errors++;
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
return { generated, errors };
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Main function
|
|
105
|
+
function main() {
|
|
106
|
+
console.log("🚀 Generating MCP skills from docs/v7/*.mdx files...\n");
|
|
107
|
+
console.log(`📂 Source: ${DOCS_DIR}`);
|
|
108
|
+
console.log(`📂 Output: ${OUTPUT_DIR}\n`);
|
|
109
|
+
|
|
110
|
+
const { generated, errors } = processFiles();
|
|
111
|
+
|
|
112
|
+
console.log(`\n✨ Complete!`);
|
|
113
|
+
console.log(` Generated: ${generated} skills`);
|
|
114
|
+
if (errors > 0) {
|
|
115
|
+
console.log(` Errors: ${errors}`);
|
|
116
|
+
}
|
|
117
|
+
console.log(`\nSkills written to: ${OUTPUT_DIR}`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// Handle command line arguments
|
|
121
|
+
if (process.argv.includes("--help") || process.argv.includes("-h")) {
|
|
122
|
+
console.log(`
|
|
123
|
+
MCP Skills Generator
|
|
124
|
+
|
|
125
|
+
Usage: node generate-skills.js [options]
|
|
126
|
+
|
|
127
|
+
Options:
|
|
128
|
+
--help, -h Show this help message
|
|
129
|
+
|
|
130
|
+
Description:
|
|
131
|
+
This script generates MCP skill files from the docs/v7/*.mdx documentation.
|
|
132
|
+
|
|
133
|
+
Each .mdx file is converted to a SKILL.md file with:
|
|
134
|
+
- name: testdriver:<filename>
|
|
135
|
+
- description: from frontmatter
|
|
136
|
+
- Content: the mdx body
|
|
137
|
+
|
|
138
|
+
Output is written to the skills/ directory.
|
|
139
|
+
`);
|
|
140
|
+
process.exit(0);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Run the script
|
|
144
|
+
try {
|
|
145
|
+
main();
|
|
146
|
+
} catch (error) {
|
|
147
|
+
console.error("❌ Error:", error.message);
|
|
148
|
+
process.exit(1);
|
|
149
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require("fs");
|
|
4
|
+
const path = require("path");
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Script to replace command references in Mintlify docs with proper links
|
|
8
|
+
*
|
|
9
|
+
* This script finds instances of command names like `hover-text`, `wait-for-text`, etc.
|
|
10
|
+
* and replaces them with proper Mintlify links to their documentation pages.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
// Get all command files from the commands directory
|
|
14
|
+
function getCommandNames() {
|
|
15
|
+
const commandsDir = path.join(__dirname, "../", "commands");
|
|
16
|
+
|
|
17
|
+
if (!fs.existsSync(commandsDir)) {
|
|
18
|
+
console.error("Commands directory not found:", commandsDir);
|
|
19
|
+
process.exit(1);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const files = fs.readdirSync(commandsDir);
|
|
23
|
+
const commands = files
|
|
24
|
+
.filter((file) => file.endsWith(".mdx"))
|
|
25
|
+
.map((file) => file.replace(".mdx", ""));
|
|
26
|
+
|
|
27
|
+
console.log("Found commands:", commands);
|
|
28
|
+
return commands;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// Process a single file
|
|
32
|
+
function processFile(filePath, commands) {
|
|
33
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
34
|
+
let modified = content;
|
|
35
|
+
let changes = 0;
|
|
36
|
+
|
|
37
|
+
commands.forEach((command) => {
|
|
38
|
+
// Create regex pattern to match `command-name` but not already linked commands
|
|
39
|
+
// This pattern looks for backtick-wrapped command names that are NOT:
|
|
40
|
+
// 1. Already inside a link: [` or preceded by ]( or ](/
|
|
41
|
+
// 2. Part of an existing link structure
|
|
42
|
+
const pattern = new RegExp(
|
|
43
|
+
`(?<!\\[)\`(${command.replace(/[-/\\^$*+?.()|[\]{}]/g, "\\$&")})\`(?!\\]\\(|\\)\\]|\\]\\(/commands/)`,
|
|
44
|
+
"g",
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const replacement = `[\`$1\`](/commands/$1)`;
|
|
48
|
+
const newContent = modified.replace(pattern, replacement);
|
|
49
|
+
|
|
50
|
+
if (newContent !== modified) {
|
|
51
|
+
const matchCount = (modified.match(pattern) || []).length;
|
|
52
|
+
console.log(` - Replaced ${matchCount} instances of \`${command}\``);
|
|
53
|
+
changes += matchCount;
|
|
54
|
+
modified = newContent;
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
return { content: modified, changes };
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// Process all .mdx files in a directory recursively
|
|
62
|
+
function processDirectory(dirPath, commands, exclude = []) {
|
|
63
|
+
const items = fs.readdirSync(dirPath);
|
|
64
|
+
let totalChanges = 0;
|
|
65
|
+
|
|
66
|
+
items.forEach((item) => {
|
|
67
|
+
const itemPath = path.join(dirPath, item);
|
|
68
|
+
const relativePath = path.relative(process.cwd(), itemPath);
|
|
69
|
+
|
|
70
|
+
// Skip excluded directories
|
|
71
|
+
if (exclude.some((ex) => relativePath.includes(ex))) {
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const stat = fs.statSync(itemPath);
|
|
76
|
+
|
|
77
|
+
if (stat.isDirectory()) {
|
|
78
|
+
totalChanges += processDirectory(itemPath, commands, exclude);
|
|
79
|
+
} else if (item.endsWith(".mdx")) {
|
|
80
|
+
console.log(`Processing: ${relativePath}`);
|
|
81
|
+
const result = processFile(itemPath, commands);
|
|
82
|
+
|
|
83
|
+
if (result.changes > 0) {
|
|
84
|
+
fs.writeFileSync(itemPath, result.content, "utf-8");
|
|
85
|
+
console.log(` ✅ Updated with ${result.changes} changes`);
|
|
86
|
+
totalChanges += result.changes;
|
|
87
|
+
} else {
|
|
88
|
+
console.log(` ⏭️ No changes needed`);
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
return totalChanges;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
// Main function
|
|
97
|
+
function main() {
|
|
98
|
+
console.log("🚀 Starting TestDriver AI docs link replacer...\n");
|
|
99
|
+
|
|
100
|
+
// Get command names from the commands directory
|
|
101
|
+
const commands = getCommandNames();
|
|
102
|
+
|
|
103
|
+
if (commands.length === 0) {
|
|
104
|
+
console.log("No commands found. Exiting.");
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
console.log(`\n📝 Processing documentation files...\n`);
|
|
109
|
+
|
|
110
|
+
// Process all .mdx files in the docs directory, excluding the commands directory itself
|
|
111
|
+
const docsDir = path.join(__dirname, "../");
|
|
112
|
+
const exclude = ["commands"]; // Don't modify the command docs themselves
|
|
113
|
+
|
|
114
|
+
const totalChanges = processDirectory(docsDir, commands, exclude);
|
|
115
|
+
|
|
116
|
+
console.log(`\n✨ Complete! Made ${totalChanges} total replacements.`);
|
|
117
|
+
|
|
118
|
+
if (totalChanges > 0) {
|
|
119
|
+
console.log("\n📋 Summary:");
|
|
120
|
+
console.log(
|
|
121
|
+
"- Command references like `hover-text` have been replaced with [`hover-text`](/commands/hover-text)",
|
|
122
|
+
);
|
|
123
|
+
console.log("- Only changed files that needed updates");
|
|
124
|
+
console.log(
|
|
125
|
+
"- Excluded the /commands directory to avoid self-referencing issues",
|
|
126
|
+
);
|
|
127
|
+
console.log("\nYou may want to review the changes before committing.");
|
|
128
|
+
} else {
|
|
129
|
+
console.log("\n🎉 All files are already properly linked!");
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Handle command line arguments
|
|
134
|
+
if (process.argv.includes("--help") || process.argv.includes("-h")) {
|
|
135
|
+
console.log(`
|
|
136
|
+
TestDriver AI Documentation Link Replacer
|
|
137
|
+
|
|
138
|
+
Usage: node link-replacer.js [options]
|
|
139
|
+
|
|
140
|
+
Options:
|
|
141
|
+
--help, -h Show this help message
|
|
142
|
+
--dry-run Show what would be changed without making actual changes (TODO)
|
|
143
|
+
|
|
144
|
+
Description:
|
|
145
|
+
This script finds command references like \`hover-text\` in your Mintlify
|
|
146
|
+
documentation and replaces them with proper links to the command reference
|
|
147
|
+
pages like [\`hover-text\`](/commands/hover-text).
|
|
148
|
+
|
|
149
|
+
The script:
|
|
150
|
+
- Scans all .mdx files in the /docs directory
|
|
151
|
+
- Excludes the /commands directory to avoid self-references
|
|
152
|
+
- Only replaces \`command-name\` patterns that aren't already linked
|
|
153
|
+
- Preserves existing links and formatting
|
|
154
|
+
`);
|
|
155
|
+
process.exit(0);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Run the script
|
|
159
|
+
try {
|
|
160
|
+
main();
|
|
161
|
+
} catch (error) {
|
|
162
|
+
console.error("❌ Error:", error.message);
|
|
163
|
+
process.exit(1);
|
|
164
|
+
}
|