testdriverai 7.2.9 → 7.2.11
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/testdriver.yml +127 -0
- package/.testdriver/last-sandbox +7 -0
- package/agent/events.js +1 -0
- package/agent/index.js +71 -54
- package/agent/lib/sandbox.js +11 -1
- package/agents.md +393 -0
- package/debug/01-table-initial.png +0 -0
- package/debug/02-after-ai-explore.png +0 -0
- package/debug/02-after-scroll.png +0 -0
- package/docs/docs.json +87 -126
- package/docs/v7/_drafts/caching.mdx +2 -2
- package/docs/v7/{getting-started → _drafts}/installation.mdx +0 -66
- package/docs/v7/{features/coverage.mdx → _drafts/powerful.mdx} +1 -90
- package/docs/v7/{features → _drafts}/scalable.mdx +126 -4
- package/docs/v7/_drafts/screenshot.mdx +155 -0
- package/docs/v7/_drafts/writing-tests.mdx +25 -0
- package/docs/v7/{api/act.mdx → ai.mdx} +27 -27
- package/docs/v7/{api/assert.mdx → assert.mdx} +3 -3
- package/docs/v7/aws-setup.mdx +338 -0
- package/docs/v7/caching.mdx +128 -0
- package/docs/v7/ci-cd.mdx +605 -0
- package/docs/v7/{api/click.mdx → click.mdx} +4 -4
- package/docs/v7/cloud.mdx +120 -0
- package/docs/v7/customizing-devices.mdx +129 -0
- package/docs/v7/{api/dashcam.mdx → dashcam.mdx} +0 -78
- package/docs/v7/{api/doubleClick.mdx → double-click.mdx} +5 -5
- package/docs/v7/{api/elements.mdx → elements.mdx} +1 -54
- package/docs/v7/enterprise.mdx +116 -0
- package/docs/v7/examples.mdx +5 -0
- package/docs/v7/{api/exec.mdx → exec.mdx} +3 -3
- package/docs/v7/{api/find.mdx → find.mdx} +17 -21
- package/docs/v7/{api/focusApplication.mdx → focus-application.mdx} +3 -3
- package/docs/v7/generating-tests.mdx +36 -0
- package/docs/v7/{api/hover.mdx → hover.mdx} +3 -3
- package/docs/v7/locating-elements.mdx +71 -0
- package/docs/v7/making-assertions.mdx +32 -0
- package/docs/v7/{api/mouseDown.mdx → mouse-down.mdx} +7 -7
- package/docs/v7/{api/mouseUp.mdx → mouse-up.mdx} +8 -8
- package/docs/v7/performing-actions.mdx +51 -0
- package/docs/v7/{api/pressKeys.mdx → press-keys.mdx} +3 -3
- package/docs/v7/quickstart.mdx +162 -0
- package/docs/v7/reusable-code.mdx +240 -0
- package/docs/v7/{api/rightClick.mdx → right-click.mdx} +5 -5
- package/docs/v7/running-tests.mdx +181 -0
- package/docs/v7/{api/scroll.mdx → scroll.mdx} +3 -3
- package/docs/v7/secrets.mdx +115 -0
- package/docs/v7/self-hosted.mdx +66 -0
- package/docs/v7/{api/type.mdx → type.mdx} +3 -3
- package/docs/v7/variables.mdx +111 -0
- package/docs/v7/waiting-for-elements.mdx +66 -0
- package/docs/v7/what-is-testdriver.mdx +54 -0
- package/lib/vitest/hooks.mjs +80 -68
- package/package.json +1 -1
- package/sdk.d.ts +22 -9
- package/sdk.js +177 -44
- package/test/manual/reconnect-provision.test.mjs +49 -0
- package/test/manual/reconnect-signin.test.mjs +41 -0
- package/test/testdriver/ai.test.mjs +30 -0
- package/test/testdriver/setup/testHelpers.mjs +0 -1
- package/test/testdriver/windows-installer.test.mjs +61 -0
- package/tests/table-sort-enrollments.test.mjs +72 -0
- package/tests/table-sort-experiment.test.mjs +42 -0
- package/tests/table-sort-setup.test.mjs +59 -0
- package/vitest.config.mjs +1 -0
- package/docs/v7/api/assertions.mdx +0 -403
- package/docs/v7/api/sandbox.mdx +0 -404
- package/docs/v7/features/ai-native.mdx +0 -413
- package/docs/v7/features/application-logs.mdx +0 -353
- package/docs/v7/features/browser-logs.mdx +0 -414
- package/docs/v7/features/cache-management.mdx +0 -402
- package/docs/v7/features/continuous-testing.mdx +0 -346
- package/docs/v7/features/data-driven-testing.mdx +0 -441
- package/docs/v7/features/easy-to-write.mdx +0 -280
- package/docs/v7/features/enterprise.mdx +0 -656
- package/docs/v7/features/fast.mdx +0 -406
- package/docs/v7/features/managed-sandboxes.mdx +0 -384
- package/docs/v7/features/network-monitoring.mdx +0 -568
- package/docs/v7/features/parallel-execution.mdx +0 -381
- package/docs/v7/features/powerful.mdx +0 -531
- package/docs/v7/features/sandbox-customization.mdx +0 -229
- package/docs/v7/features/stable.mdx +0 -473
- package/docs/v7/features/system-performance.mdx +0 -616
- package/docs/v7/features/test-analytics.mdx +0 -373
- package/docs/v7/features/test-cases.mdx +0 -393
- package/docs/v7/features/test-replays.mdx +0 -408
- package/docs/v7/features/test-reports.mdx +0 -308
- package/docs/v7/getting-started/debugging-tests.mdx +0 -382
- package/docs/v7/getting-started/quickstart.mdx +0 -90
- package/docs/v7/getting-started/running-tests.mdx +0 -173
- package/docs/v7/getting-started/setting-up-in-ci.mdx +0 -612
- package/docs/v7/getting-started/writing-tests.mdx +0 -534
- package/docs/v7/overview/what-is-testdriver.mdx +0 -386
- package/docs/v7/presets/chrome-extension.mdx +0 -248
- package/docs/v7/presets/chrome.mdx +0 -300
- package/docs/v7/presets/electron.mdx +0 -460
- package/docs/v7/presets/vscode.mdx +0 -417
- package/docs/v7/presets/webapp.mdx +0 -393
- package/vitest.config.js +0 -18
- /package/docs/v7/{commands → _drafts/commands}/assert.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/exec.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/focus-application.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/hover-image.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/hover-text.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/if.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/match-image.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/press-keys.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/remember.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/run.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/scroll-until-image.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/scroll-until-text.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/scroll.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/type.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/wait-for-image.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/wait-for-text.mdx +0 -0
- /package/docs/v7/{commands → _drafts/commands}/wait.mdx +0 -0
- /package/docs/v7/{getting-started → _drafts}/configuration.mdx +0 -0
- /package/docs/v7/{features → _drafts}/observable.mdx +0 -0
- /package/docs/v7/{platforms → _drafts/platforms}/linux.mdx +0 -0
- /package/docs/v7/{platforms → _drafts/platforms}/macos.mdx +0 -0
- /package/docs/v7/{platforms → _drafts/platforms}/windows.mdx +0 -0
- /package/docs/v7/{playwright.mdx → _drafts/playwright.mdx} +0 -0
- /package/docs/v7/{overview → _drafts}/readme.mdx +0 -0
- /package/docs/v7/{features → _drafts}/reports.mdx +0 -0
- /package/docs/v7/{api/client.mdx → client.mdx} +0 -0
|
@@ -1,441 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
title: "Data-Driven Testing"
|
|
3
|
-
description: "Build maintainable test suites with reusable code and dynamic test data"
|
|
4
|
-
icon: "table"
|
|
5
|
-
---
|
|
6
|
-
|
|
7
|
-
Scale your test suite with reusable code patterns and dynamic data to reduce duplication and maintain consistency across thousands of tests.
|
|
8
|
-
|
|
9
|
-
## Code Snippets for Reusability
|
|
10
|
-
|
|
11
|
-
Scale your test suite with reusable code snippets to reduce duplication and maintain consistency:
|
|
12
|
-
|
|
13
|
-
<Tabs>
|
|
14
|
-
<Tab title="Helper Functions">
|
|
15
|
-
```javascript test/helpers/auth.js
|
|
16
|
-
// Reusable authentication helpers
|
|
17
|
-
export async function login(testdriver, { email, password }) {
|
|
18
|
-
await testdriver.find('email input').type(email);
|
|
19
|
-
await testdriver.find('password input').type(password);
|
|
20
|
-
await testdriver.find('login button').click();
|
|
21
|
-
await testdriver.assert('logged in successfully');
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export async function logout(testdriver) {
|
|
25
|
-
await testdriver.find('user menu').click();
|
|
26
|
-
await testdriver.find('logout button').click();
|
|
27
|
-
}
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
```javascript test/checkout.test.js
|
|
31
|
-
import { login } from './helpers/auth.js';
|
|
32
|
-
|
|
33
|
-
test('checkout flow', async (context) => {
|
|
34
|
-
const { testdriver } = await chrome(context, { url });
|
|
35
|
-
await login(testdriver, {
|
|
36
|
-
email: 'user@example.com',
|
|
37
|
-
password: 'password123'
|
|
38
|
-
});
|
|
39
|
-
// Continue with checkout test
|
|
40
|
-
});
|
|
41
|
-
```
|
|
42
|
-
</Tab>
|
|
43
|
-
|
|
44
|
-
<Tab title="Page Objects">
|
|
45
|
-
```javascript test/pages/LoginPage.js
|
|
46
|
-
export class LoginPage {
|
|
47
|
-
constructor(testdriver) {
|
|
48
|
-
this.testdriver = testdriver;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
async login(email, password) {
|
|
52
|
-
await this.testdriver.find('email input').type(email);
|
|
53
|
-
await this.testdriver.find('password input').type(password);
|
|
54
|
-
await this.testdriver.find('submit button').click();
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
async assertError(message) {
|
|
58
|
-
await this.testdriver.assert(`error message shows "${message}"`);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
```
|
|
62
|
-
|
|
63
|
-
```javascript test/auth.test.js
|
|
64
|
-
import { LoginPage } from './pages/LoginPage.js';
|
|
65
|
-
|
|
66
|
-
test('invalid login shows error', async (context) => {
|
|
67
|
-
const { testdriver } = await chrome(context, { url });
|
|
68
|
-
const loginPage = new LoginPage(testdriver);
|
|
69
|
-
|
|
70
|
-
await loginPage.login('invalid@test.com', 'wrong');
|
|
71
|
-
await loginPage.assertError('Invalid credentials');
|
|
72
|
-
});
|
|
73
|
-
```
|
|
74
|
-
</Tab>
|
|
75
|
-
|
|
76
|
-
<Tab title="Custom Commands">
|
|
77
|
-
```javascript test/commands/navigation.js
|
|
78
|
-
export function addNavigationCommands(testdriver) {
|
|
79
|
-
testdriver.navigateTo = async (section) => {
|
|
80
|
-
await testdriver.find(`${section} nav link`).click();
|
|
81
|
-
await testdriver.assert(`${section} page is loaded`);
|
|
82
|
-
};
|
|
83
|
-
|
|
84
|
-
testdriver.searchFor = async (query) => {
|
|
85
|
-
await testdriver.find('search input').type(query);
|
|
86
|
-
await testdriver.find('search button').click();
|
|
87
|
-
await testdriver.assert('search results are displayed');
|
|
88
|
-
};
|
|
89
|
-
|
|
90
|
-
return testdriver;
|
|
91
|
-
}
|
|
92
|
-
```
|
|
93
|
-
|
|
94
|
-
```javascript test/search.test.js
|
|
95
|
-
import { addNavigationCommands } from './commands/navigation.js';
|
|
96
|
-
|
|
97
|
-
test('search functionality', async (context) => {
|
|
98
|
-
let { testdriver } = await chrome(context, { url });
|
|
99
|
-
testdriver = addNavigationCommands(testdriver);
|
|
100
|
-
|
|
101
|
-
await testdriver.searchFor('laptop');
|
|
102
|
-
// Custom command used
|
|
103
|
-
});
|
|
104
|
-
```
|
|
105
|
-
</Tab>
|
|
106
|
-
</Tabs>
|
|
107
|
-
|
|
108
|
-
<Check>
|
|
109
|
-
Reusable snippets reduce test maintenance time by up to 70% in large test suites.
|
|
110
|
-
</Check>
|
|
111
|
-
|
|
112
|
-
## Dynamic Variables for Data-Driven Tests
|
|
113
|
-
|
|
114
|
-
Scale your testing with dynamic data to cover more scenarios:
|
|
115
|
-
|
|
116
|
-
<Tabs>
|
|
117
|
-
<Tab title="Environment Variables">
|
|
118
|
-
```javascript
|
|
119
|
-
import { test } from 'vitest';
|
|
120
|
-
import { chrome } from 'testdriverai/presets';
|
|
121
|
-
|
|
122
|
-
test('multi-environment testing', async (context) => {
|
|
123
|
-
const env = process.env.TEST_ENV || 'staging';
|
|
124
|
-
const urls = {
|
|
125
|
-
dev: 'https://dev.myapp.com',
|
|
126
|
-
staging: 'https://staging.myapp.com',
|
|
127
|
-
production: 'https://myapp.com'
|
|
128
|
-
};
|
|
129
|
-
|
|
130
|
-
const { testdriver } = await chrome(context, {
|
|
131
|
-
url: urls[env]
|
|
132
|
-
});
|
|
133
|
-
|
|
134
|
-
await testdriver.assert('app is running');
|
|
135
|
-
});
|
|
136
|
-
```
|
|
137
|
-
|
|
138
|
-
```bash
|
|
139
|
-
# Run against different environments
|
|
140
|
-
TEST_ENV=dev npx vitest run
|
|
141
|
-
TEST_ENV=staging npx vitest run
|
|
142
|
-
TEST_ENV=production npx vitest run
|
|
143
|
-
```
|
|
144
|
-
</Tab>
|
|
145
|
-
|
|
146
|
-
<Tab title="Test Fixtures">
|
|
147
|
-
```javascript test/fixtures/users.js
|
|
148
|
-
export const testUsers = [
|
|
149
|
-
{ email: 'admin@test.com', role: 'admin' },
|
|
150
|
-
{ email: 'user@test.com', role: 'user' },
|
|
151
|
-
{ email: 'guest@test.com', role: 'guest' }
|
|
152
|
-
];
|
|
153
|
-
|
|
154
|
-
export const products = [
|
|
155
|
-
{ name: 'Laptop', price: 999 },
|
|
156
|
-
{ name: 'Mouse', price: 29 },
|
|
157
|
-
{ name: 'Keyboard', price: 89 }
|
|
158
|
-
];
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
```javascript test/permissions.test.js
|
|
162
|
-
import { test } from 'vitest';
|
|
163
|
-
import { chrome } from 'testdriverai/presets';
|
|
164
|
-
import { testUsers } from './fixtures/users.js';
|
|
165
|
-
|
|
166
|
-
test.each(testUsers)('$role can access dashboard', async ({ email, role }, context) => {
|
|
167
|
-
const { testdriver } = await chrome(context, { url });
|
|
168
|
-
|
|
169
|
-
await testdriver.find('email input').type(email);
|
|
170
|
-
await testdriver.find('password input').type('password123');
|
|
171
|
-
await testdriver.find('login button').click();
|
|
172
|
-
|
|
173
|
-
if (role === 'admin') {
|
|
174
|
-
await testdriver.assert('admin panel is visible');
|
|
175
|
-
} else {
|
|
176
|
-
await testdriver.assert('user dashboard is visible');
|
|
177
|
-
}
|
|
178
|
-
});
|
|
179
|
-
```
|
|
180
|
-
</Tab>
|
|
181
|
-
|
|
182
|
-
<Tab title="Dynamic Data Generation">
|
|
183
|
-
```javascript
|
|
184
|
-
import { test } from 'vitest';
|
|
185
|
-
import { chrome } from 'testdriverai/presets';
|
|
186
|
-
import { faker } from '@faker-js/faker';
|
|
187
|
-
|
|
188
|
-
test('user registration with dynamic data', async (context) => {
|
|
189
|
-
const { testdriver } = await chrome(context, { url });
|
|
190
|
-
|
|
191
|
-
// Generate unique test data for each run
|
|
192
|
-
const userData = {
|
|
193
|
-
firstName: faker.person.firstName(),
|
|
194
|
-
lastName: faker.person.lastName(),
|
|
195
|
-
email: faker.internet.email(),
|
|
196
|
-
password: faker.internet.password({ length: 12 })
|
|
197
|
-
};
|
|
198
|
-
|
|
199
|
-
await testdriver.find('first name input').type(userData.firstName);
|
|
200
|
-
await testdriver.find('last name input').type(userData.lastName);
|
|
201
|
-
await testdriver.find('email input').type(userData.email);
|
|
202
|
-
await testdriver.find('password input').type(userData.password);
|
|
203
|
-
await testdriver.find('register button').click();
|
|
204
|
-
|
|
205
|
-
await testdriver.assert('registration successful');
|
|
206
|
-
console.log('Registered user:', userData.email);
|
|
207
|
-
});
|
|
208
|
-
```
|
|
209
|
-
|
|
210
|
-
```bash
|
|
211
|
-
npm install --save-dev @faker-js/faker
|
|
212
|
-
```
|
|
213
|
-
</Tab>
|
|
214
|
-
</Tabs>
|
|
215
|
-
|
|
216
|
-
<Card title="Dynamic Variables Best Practices" icon="lightbulb">
|
|
217
|
-
- **Environment configs:** Store URLs, credentials, and settings in env vars
|
|
218
|
-
- **Test fixtures:** Maintain reusable test data in separate files
|
|
219
|
-
- **Data generators:** Use libraries like Faker for unique test data
|
|
220
|
-
- **Parameterization:** Test multiple scenarios with `test.each()`
|
|
221
|
-
- **CI/CD integration:** Pass dynamic values via environment variables
|
|
222
|
-
</Card>
|
|
223
|
-
|
|
224
|
-
## Secure Secrets Management
|
|
225
|
-
|
|
226
|
-
Protect sensitive data in your tests with built-in secrets handling:
|
|
227
|
-
|
|
228
|
-
<Tabs>
|
|
229
|
-
<Tab title="Secret Type Option">
|
|
230
|
-
```javascript
|
|
231
|
-
import { test } from 'vitest';
|
|
232
|
-
import { chrome } from 'testdriverai/presets';
|
|
233
|
-
|
|
234
|
-
test('login with secret password', async (context) => {
|
|
235
|
-
const { testdriver } = await chrome(context, { url });
|
|
236
|
-
|
|
237
|
-
await testdriver.find('email input').type('user@example.com');
|
|
238
|
-
|
|
239
|
-
// Password is never logged or cached
|
|
240
|
-
await testdriver.find('password input').type(process.env.TEST_PASSWORD, {
|
|
241
|
-
secret: true
|
|
242
|
-
});
|
|
243
|
-
|
|
244
|
-
await testdriver.find('login button').click();
|
|
245
|
-
await testdriver.assert('logged in successfully');
|
|
246
|
-
});
|
|
247
|
-
```
|
|
248
|
-
|
|
249
|
-
<Check>
|
|
250
|
-
The `secret: true` option prevents sensitive data from appearing in logs, dashcam replays, or cache entries.
|
|
251
|
-
</Check>
|
|
252
|
-
</Tab>
|
|
253
|
-
|
|
254
|
-
<Tab title="Environment Variables">
|
|
255
|
-
```javascript
|
|
256
|
-
// .env.test
|
|
257
|
-
TEST_PASSWORD=my-secret-password
|
|
258
|
-
TEST_API_KEY=sk-1234567890abcdef
|
|
259
|
-
TEST_CREDIT_CARD=4111111111111111
|
|
260
|
-
|
|
261
|
-
// test/auth.test.js
|
|
262
|
-
import { test } from 'vitest';
|
|
263
|
-
import { chrome } from 'testdriverai/presets';
|
|
264
|
-
|
|
265
|
-
test('secure authentication', async (context) => {
|
|
266
|
-
const { testdriver } = await chrome(context, { url });
|
|
267
|
-
|
|
268
|
-
// Load secrets from environment
|
|
269
|
-
await testdriver.find('password input').type(
|
|
270
|
-
process.env.TEST_PASSWORD,
|
|
271
|
-
{ secret: true }
|
|
272
|
-
);
|
|
273
|
-
|
|
274
|
-
await testdriver.find('api key input').type(
|
|
275
|
-
process.env.TEST_API_KEY,
|
|
276
|
-
{ secret: true }
|
|
277
|
-
);
|
|
278
|
-
});
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
```bash
|
|
282
|
-
# Install dotenv for local development
|
|
283
|
-
npm install --save-dev dotenv
|
|
284
|
-
|
|
285
|
-
# Load in test setup
|
|
286
|
-
import 'dotenv/config';
|
|
287
|
-
```
|
|
288
|
-
</Tab>
|
|
289
|
-
|
|
290
|
-
<Tab title="CI/CD Secrets">
|
|
291
|
-
```yaml .github/workflows/test.yml
|
|
292
|
-
name: E2E Tests
|
|
293
|
-
|
|
294
|
-
on: [push, pull_request]
|
|
295
|
-
|
|
296
|
-
jobs:
|
|
297
|
-
test:
|
|
298
|
-
runs-on: ubuntu-latest
|
|
299
|
-
steps:
|
|
300
|
-
- uses: actions/checkout@v3
|
|
301
|
-
- uses: actions/setup-node@v3
|
|
302
|
-
- run: npm install
|
|
303
|
-
- run: npx vitest run
|
|
304
|
-
env:
|
|
305
|
-
TD_API_KEY: ${{ secrets.TD_API_KEY }}
|
|
306
|
-
TEST_PASSWORD: ${{ secrets.TEST_PASSWORD }}
|
|
307
|
-
TEST_API_KEY: ${{ secrets.TEST_API_KEY }}
|
|
308
|
-
```
|
|
309
|
-
|
|
310
|
-
Configure secrets in your CI/CD platform:
|
|
311
|
-
- **GitHub:** Settings → Secrets and variables → Actions
|
|
312
|
-
- **GitLab:** Settings → CI/CD → Variables
|
|
313
|
-
- **CircleCI:** Project Settings → Environment Variables
|
|
314
|
-
</Tab>
|
|
315
|
-
|
|
316
|
-
<Tab title="Helper Functions">
|
|
317
|
-
```javascript test/helpers/secrets.js
|
|
318
|
-
// Centralized secret handling
|
|
319
|
-
export function getSecret(key) {
|
|
320
|
-
const value = process.env[key];
|
|
321
|
-
if (!value) {
|
|
322
|
-
throw new Error(`Secret ${key} not found in environment`);
|
|
323
|
-
}
|
|
324
|
-
return value;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
export async function typeSecret(testdriver, selector, secretKey) {
|
|
328
|
-
const value = getSecret(secretKey);
|
|
329
|
-
await testdriver.find(selector).type(value, { secret: true });
|
|
330
|
-
}
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
```javascript test/payment.test.js
|
|
334
|
-
import { typeSecret } from './helpers/secrets.js';
|
|
335
|
-
|
|
336
|
-
test('payment form', async (context) => {
|
|
337
|
-
const { testdriver } = await chrome(context, { url });
|
|
338
|
-
|
|
339
|
-
await typeSecret(testdriver, 'credit card input', 'TEST_CREDIT_CARD');
|
|
340
|
-
await typeSecret(testdriver, 'cvv input', 'TEST_CVV');
|
|
341
|
-
|
|
342
|
-
await testdriver.find('submit payment').click();
|
|
343
|
-
});
|
|
344
|
-
```
|
|
345
|
-
</Tab>
|
|
346
|
-
</Tabs>
|
|
347
|
-
|
|
348
|
-
<Warning>
|
|
349
|
-
Never hardcode secrets in test files or commit them to version control. Always use environment variables or secure secret management systems.
|
|
350
|
-
</Warning>
|
|
351
|
-
|
|
352
|
-
## Familiar Test Syntax
|
|
353
|
-
|
|
354
|
-
TestDriver works with the test frameworks you already know:
|
|
355
|
-
|
|
356
|
-
<Tabs>
|
|
357
|
-
<Tab title="Vitest">
|
|
358
|
-
```javascript
|
|
359
|
-
import { test, describe, beforeAll, afterAll } from 'vitest';
|
|
360
|
-
import { chrome } from 'testdriverai/presets';
|
|
361
|
-
|
|
362
|
-
describe('My Feature', () => {
|
|
363
|
-
test('should work', async (context) => {
|
|
364
|
-
const { testdriver } = await chrome(context, { url });
|
|
365
|
-
await testdriver.find('button').click();
|
|
366
|
-
});
|
|
367
|
-
});
|
|
368
|
-
```
|
|
369
|
-
</Tab>
|
|
370
|
-
|
|
371
|
-
<Tab title="Jest">
|
|
372
|
-
```javascript
|
|
373
|
-
import { chrome } from 'testdriverai/presets';
|
|
374
|
-
|
|
375
|
-
describe('My Feature', () => {
|
|
376
|
-
test('should work', async () => {
|
|
377
|
-
const { testdriver } = await chrome({ url });
|
|
378
|
-
await testdriver.find('button').click();
|
|
379
|
-
});
|
|
380
|
-
});
|
|
381
|
-
```
|
|
382
|
-
</Tab>
|
|
383
|
-
|
|
384
|
-
<Tab title="Mocha">
|
|
385
|
-
```javascript
|
|
386
|
-
import { chrome } from 'testdriverai/presets';
|
|
387
|
-
|
|
388
|
-
describe('My Feature', function() {
|
|
389
|
-
it('should work', async function() {
|
|
390
|
-
const { testdriver } = await chrome(this, { url });
|
|
391
|
-
await testdriver.find('button').click();
|
|
392
|
-
});
|
|
393
|
-
});
|
|
394
|
-
```
|
|
395
|
-
</Tab>
|
|
396
|
-
</Tabs>
|
|
397
|
-
|
|
398
|
-
## Existing Systems Integration
|
|
399
|
-
|
|
400
|
-
Drop TestDriver into your current workflow without disruption:
|
|
401
|
-
|
|
402
|
-
```javascript
|
|
403
|
-
import { test, expect } from 'vitest';
|
|
404
|
-
import { chrome } from 'testdriverai/presets';
|
|
405
|
-
|
|
406
|
-
test('integrates with existing assertions', async (context) => {
|
|
407
|
-
const { testdriver } = await chrome(context, { url });
|
|
408
|
-
|
|
409
|
-
// Use TestDriver's AI assertions
|
|
410
|
-
await testdriver.assert('welcome message is visible');
|
|
411
|
-
|
|
412
|
-
// Or use traditional assertions
|
|
413
|
-
const button = await testdriver.find('submit button');
|
|
414
|
-
expect(button.coordinates).toBeDefined();
|
|
415
|
-
expect(button.text).toContain('Submit');
|
|
416
|
-
|
|
417
|
-
// Mix and match as needed
|
|
418
|
-
const element = await testdriver.exec('js', 'document.title');
|
|
419
|
-
expect(element).toBe('My App');
|
|
420
|
-
});
|
|
421
|
-
```
|
|
422
|
-
|
|
423
|
-
## Learn More
|
|
424
|
-
|
|
425
|
-
<CardGroup cols={2}>
|
|
426
|
-
<Card
|
|
427
|
-
title="Vitest Integration"
|
|
428
|
-
icon="flask-vial"
|
|
429
|
-
href="/v7/guides/vitest"
|
|
430
|
-
>
|
|
431
|
-
Complete Vitest guide
|
|
432
|
-
</Card>
|
|
433
|
-
|
|
434
|
-
<Card
|
|
435
|
-
title="Continuous Testing"
|
|
436
|
-
icon="arrows-spin"
|
|
437
|
-
href="/v7/features/continuous-testing"
|
|
438
|
-
>
|
|
439
|
-
CI/CD integration and scaling
|
|
440
|
-
</Card>
|
|
441
|
-
</CardGroup>
|