testdriverai 7.0.0 โ 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/AGENTS.md +550 -0
- package/CODEOWNERS +0 -1
- package/README.md +126 -0
- package/agent/index.js +43 -18
- package/agent/lib/commands.js +794 -135
- package/agent/lib/redraw.js +124 -39
- package/agent/lib/sandbox.js +10 -1
- package/agent/lib/sdk.js +21 -0
- package/docs/MIGRATION.md +425 -0
- package/docs/PRESETS.md +210 -0
- package/docs/docs.json +91 -37
- package/docs/guide/best-practices-polling.mdx +154 -0
- package/docs/v7/api/dashcam.mdx +497 -0
- package/docs/v7/api/doubleClick.mdx +102 -0
- package/docs/v7/api/mouseDown.mdx +161 -0
- package/docs/v7/api/mouseUp.mdx +164 -0
- package/docs/v7/api/rightClick.mdx +123 -0
- package/docs/v7/getting-started/configuration.mdx +380 -0
- package/docs/v7/getting-started/quickstart.mdx +273 -140
- 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/performance.mdx +517 -0
- 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/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/interfaces/vitest-plugin.mjs +186 -100
- package/package.json +12 -1
- package/sdk.d.ts +335 -42
- package/sdk.js +756 -95
- 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/testdriver/acceptance-sdk/assert.test.mjs +13 -31
- 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 +7 -19
- package/testdriver/acceptance-sdk/element-not-found.test.mjs +6 -19
- package/testdriver/acceptance-sdk/exec-js.test.mjs +6 -18
- package/testdriver/acceptance-sdk/exec-output.test.mjs +8 -20
- package/testdriver/acceptance-sdk/exec-pwsh.test.mjs +13 -25
- package/testdriver/acceptance-sdk/focus-window.test.mjs +8 -20
- package/testdriver/acceptance-sdk/formatted-logging.test.mjs +5 -20
- package/testdriver/acceptance-sdk/hooks-example.test.mjs +38 -0
- package/testdriver/acceptance-sdk/hover-image.test.mjs +10 -19
- package/testdriver/acceptance-sdk/hover-text-with-description.test.mjs +7 -19
- package/testdriver/acceptance-sdk/hover-text.test.mjs +5 -19
- package/testdriver/acceptance-sdk/match-image.test.mjs +7 -19
- package/testdriver/acceptance-sdk/presets-example.test.mjs +87 -0
- package/testdriver/acceptance-sdk/press-keys.test.mjs +5 -19
- package/testdriver/acceptance-sdk/prompt.test.mjs +6 -18
- package/testdriver/acceptance-sdk/scroll-keyboard.test.mjs +6 -20
- package/testdriver/acceptance-sdk/scroll-until-image.test.mjs +6 -18
- package/testdriver/acceptance-sdk/scroll-until-text.test.mjs +9 -23
- package/testdriver/acceptance-sdk/scroll.test.mjs +12 -21
- package/testdriver/acceptance-sdk/setup/testHelpers.mjs +124 -352
- 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.test.mjs +19 -58
- package/vitest.config.mjs +1 -0
- package/.vscode/mcp.json +0 -9
- package/MIGRATION.md +0 -389
- package/PLUGIN_MIGRATION.md +0 -222
- package/PROMPT_CACHE.md +0 -200
- package/SDK_LOGGING.md +0 -222
- package/SDK_MIGRATION.md +0 -474
- package/SDK_README.md +0 -1122
- package/debug-screenshot-1763401388589.png +0 -0
- package/examples/run-tests-with-recording.sh +0 -70
- package/examples/screenshot-example.js +0 -63
- package/examples/sdk-awesome-logs-demo.js +0 -177
- package/examples/sdk-cache-thresholds.js +0 -96
- package/examples/sdk-element-properties.js +0 -155
- package/examples/sdk-simple-example.js +0 -65
- package/examples/test-recording-example.test.js +0 -166
- package/mcp-server/AI_GUIDELINES.md +0 -57
- package/test-find-api.js +0 -73
- package/test-prompt-cache.js +0 -96
- package/test-sandbox-render.js +0 -28
- package/test-sdk-methods.js +0 -15
- package/test-sdk-refactor.js +0 -53
- package/test-stack-trace.mjs +0 -57
- package/testdriver/acceptance-sdk/setup/lifecycleHelpers.mjs +0 -239
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { chrome } from "../../src/presets/index.mjs";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* CHECKPOINT SYSTEM GUIDE FOR TESTDRIVER TESTS
|
|
6
|
+
* ============================================
|
|
7
|
+
*
|
|
8
|
+
* When newSandbox is set to false in chrome(), the sandbox persists between test runs.
|
|
9
|
+
* This allows you to skip completed steps when debugging or developing tests.
|
|
10
|
+
*
|
|
11
|
+
* HOW TO USE CHECKPOINTS:
|
|
12
|
+
*
|
|
13
|
+
* 1. Run your test normally until it fails at a certain step
|
|
14
|
+
* 2. Find the checkpoint comment just before the failing section (e.g., "// CHECKPOINT: Login Complete")
|
|
15
|
+
* 3. Comment out all code BEFORE that checkpoint using /* ... *\/ block comments
|
|
16
|
+
* 4. Re-run the test - it will resume from that checkpoint using the existing sandbox state
|
|
17
|
+
* 5. Once the test passes completely, uncomment all sections to verify end-to-end
|
|
18
|
+
*
|
|
19
|
+
* CHECKPOINT LOCATIONS IN THIS TEST:
|
|
20
|
+
* - CHECKPOINT 1: Cookie banner handled
|
|
21
|
+
* - CHECKPOINT 2: Login complete
|
|
22
|
+
* - CHECKPOINT 3: Patients page loaded
|
|
23
|
+
* - CHECKPOINT 4: Patient selected/created
|
|
24
|
+
* - CHECKPOINT 5: Patient profile opened
|
|
25
|
+
*
|
|
26
|
+
* IMPORTANT: Always set newSandbox: false in chrome() options to enable this feature!
|
|
27
|
+
*
|
|
28
|
+
* FOR AI ASSISTANTS:
|
|
29
|
+
* When helping users debug TestDriver tests:
|
|
30
|
+
* - If a test fails at a certain step, suggest commenting out earlier checkpoints
|
|
31
|
+
* - Remind them to set newSandbox: false
|
|
32
|
+
* - After fixes, remind them to uncomment all code for full end-to-end validation
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
// Helper function to poll for an element until it's found
|
|
36
|
+
async function waitForElement(testdriver, description, maxAttempts = 10, delayMs = 1000) {
|
|
37
|
+
for (let i = 0; i < maxAttempts; i++) {
|
|
38
|
+
try {
|
|
39
|
+
const element = await testdriver.find(description);
|
|
40
|
+
if (element.found()) {
|
|
41
|
+
return element;
|
|
42
|
+
}
|
|
43
|
+
} catch (e) {
|
|
44
|
+
if (i === maxAttempts - 1) throw e;
|
|
45
|
+
}
|
|
46
|
+
await new Promise(resolve => setTimeout(resolve, delayMs));
|
|
47
|
+
}
|
|
48
|
+
throw new Error(`Element not found after ${maxAttempts} attempts: ${description}`);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
describe("Sully.ai Patient Management Workflow", () => {
|
|
52
|
+
it("should complete full patient workflow: login, view patients, update note, and edit profile", async (context) => {
|
|
53
|
+
const { testdriver } = await chrome(context, {
|
|
54
|
+
url: 'https://app.sully.ai',
|
|
55
|
+
redrawThreshold: { enabled: true }
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
// ========================================================================
|
|
59
|
+
// CHECKPOINT 1: Cookie Banner
|
|
60
|
+
// If test fails after this point, comment out this section (lines above)
|
|
61
|
+
// ========================================================================
|
|
62
|
+
|
|
63
|
+
// Handle cookie banner if present
|
|
64
|
+
try {
|
|
65
|
+
const acceptCookies = await testdriver.find("Accept All button for cookies");
|
|
66
|
+
await acceptCookies.click();
|
|
67
|
+
} catch {
|
|
68
|
+
console.log("No cookie banner or already dismissed");
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Wait for login page to load by polling for email field
|
|
72
|
+
console.log("Waiting for login page to load...");
|
|
73
|
+
const emailField = await waitForElement(testdriver, "Email input field");
|
|
74
|
+
console.log("Found email field");
|
|
75
|
+
await emailField.click();
|
|
76
|
+
await testdriver.type("razeen+testdriver@sully.ai");
|
|
77
|
+
|
|
78
|
+
const passwordField = await testdriver.find("Password input field");
|
|
79
|
+
await passwordField.click();
|
|
80
|
+
await testdriver.type("plmokn7@A", {secret: true});
|
|
81
|
+
|
|
82
|
+
const loginButton = await testdriver.find("Login button");
|
|
83
|
+
await loginButton.click();
|
|
84
|
+
|
|
85
|
+
// ========================================================================
|
|
86
|
+
// CHECKPOINT 2: Login Complete
|
|
87
|
+
// If test fails after this point, comment out all code above this checkpoint
|
|
88
|
+
// ========================================================================
|
|
89
|
+
|
|
90
|
+
// Wait for navigation to complete after login
|
|
91
|
+
console.log("Waiting for login to process...");
|
|
92
|
+
await new Promise(resolve => setTimeout(resolve, 5000));
|
|
93
|
+
|
|
94
|
+
// Take a screenshot to see where we are
|
|
95
|
+
await testdriver.screenshot();
|
|
96
|
+
console.log("Screenshot taken after login");
|
|
97
|
+
|
|
98
|
+
// Verify login successful
|
|
99
|
+
const loginSuccess = await testdriver.assert("user is logged in and on the main application page or dashboard");
|
|
100
|
+
expect(loginSuccess).toBeTruthy();
|
|
101
|
+
|
|
102
|
+
// Poll for dashboard element to ensure login completed
|
|
103
|
+
console.log("Looking for Patients link...");
|
|
104
|
+
await waitForElement(testdriver, "Patients button or link in the navigation menu", 15, 1000);
|
|
105
|
+
|
|
106
|
+
// Dismiss password save dialog first if it appears
|
|
107
|
+
try {
|
|
108
|
+
const neverButton = await testdriver.find("Never button or Never save button");
|
|
109
|
+
await neverButton.click();
|
|
110
|
+
console.log("Dismissed password save dialog");
|
|
111
|
+
} catch {
|
|
112
|
+
console.log("Password save dialog not found");
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
await testdriver.find("save profile changes popup or banner").click();
|
|
116
|
+
|
|
117
|
+
// Click Patients
|
|
118
|
+
const patientsLink = await testdriver.find("Patients navigation link or menu item");
|
|
119
|
+
await patientsLink.click();
|
|
120
|
+
|
|
121
|
+
// ========================================================================
|
|
122
|
+
// CHECKPOINT 3: Patients Page Loaded
|
|
123
|
+
// If test fails after this point, comment out all code above this checkpoint
|
|
124
|
+
// ========================================================================
|
|
125
|
+
|
|
126
|
+
// Approach 1: Search for existing patient
|
|
127
|
+
const existingPatientInput = await testdriver.find("Patient search input box");
|
|
128
|
+
await existingPatientInput.click();
|
|
129
|
+
|
|
130
|
+
// Type a search term to find a patient
|
|
131
|
+
await testdriver.type("Patient Test");
|
|
132
|
+
|
|
133
|
+
// Poll for search results to appear
|
|
134
|
+
const firstPatient = await waitForElement(testdriver, "first patient name in the dropdown or list", 5, 500);
|
|
135
|
+
await firstPatient.click();
|
|
136
|
+
|
|
137
|
+
console.log("Found patient via search");
|
|
138
|
+
|
|
139
|
+
// Verify patient visit page or details are loaded
|
|
140
|
+
const patientLoaded = await testdriver.assert("we are on a patient recording page");
|
|
141
|
+
expect(patientLoaded).toBeTruthy();
|
|
142
|
+
|
|
143
|
+
// ========================================================================
|
|
144
|
+
// CHECKPOINT 4: Patient Selected/Created
|
|
145
|
+
// If test fails after this point, comment out all code above this checkpoint
|
|
146
|
+
// ========================================================================
|
|
147
|
+
|
|
148
|
+
await testdriver.find('input box at the bottom of the screen').click();
|
|
149
|
+
await testdriver.type("This is a test note added by TestDriver automation.");
|
|
150
|
+
|
|
151
|
+
// Regenerate note - click make note more concise
|
|
152
|
+
console.log("Looking for note regeneration option...");
|
|
153
|
+
try {
|
|
154
|
+
const makeNoteConcise = await testdriver.find("Make note more concise button or option");
|
|
155
|
+
await makeNoteConcise.click();
|
|
156
|
+
console.log("Clicked make note more concise");
|
|
157
|
+
|
|
158
|
+
// Wait for note to regenerate
|
|
159
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
160
|
+
|
|
161
|
+
// Verify note regeneration completed
|
|
162
|
+
const noteRegenerated = await testdriver.assert("note has been regenerated or updated");
|
|
163
|
+
expect(noteRegenerated).toBeTruthy();
|
|
164
|
+
} catch {
|
|
165
|
+
console.log("Could not find or click make note more concise option");
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
// Look for kebab menu on the right to access patient profile
|
|
169
|
+
console.log("Looking for kebab menu on the right...");
|
|
170
|
+
|
|
171
|
+
// Try to find the menu - it might be a three-dot menu or settings icon on the right side
|
|
172
|
+
const kebabMenu = await testdriver.find("three dots menu or kebab menu on the right side of the page");
|
|
173
|
+
await kebabMenu.click();
|
|
174
|
+
|
|
175
|
+
// Wait for menu to open
|
|
176
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
177
|
+
|
|
178
|
+
// Look for patient profile option
|
|
179
|
+
const patientProfile = await testdriver.find("Patient Profile or Edit Profile option in menu");
|
|
180
|
+
await patientProfile.click();
|
|
181
|
+
|
|
182
|
+
// Wait for patient profile form to load
|
|
183
|
+
await new Promise(resolve => setTimeout(resolve, 3000));
|
|
184
|
+
|
|
185
|
+
// Verify patient profile form is displayed
|
|
186
|
+
const profileForm = await testdriver.assert("patient profile form or edit patient page is visible");
|
|
187
|
+
expect(profileForm).toBeTruthy();
|
|
188
|
+
|
|
189
|
+
// ========================================================================
|
|
190
|
+
// CHECKPOINT 5: Patient Profile Opened
|
|
191
|
+
// If test fails after this point, comment out all code above this checkpoint
|
|
192
|
+
// ========================================================================
|
|
193
|
+
|
|
194
|
+
// Fill out patient details
|
|
195
|
+
console.log("Filling out patient details...");
|
|
196
|
+
try {
|
|
197
|
+
// Look for phone number field as an example
|
|
198
|
+
const phoneField = await testdriver.find("phone number field or mobile number input");
|
|
199
|
+
await phoneField.click();
|
|
200
|
+
await testdriver.type("555-0123");
|
|
201
|
+
console.log("Filled phone number");
|
|
202
|
+
|
|
203
|
+
// Look for email field
|
|
204
|
+
try {
|
|
205
|
+
const emailFieldProfile = await testdriver.find("email address field in the patient profile");
|
|
206
|
+
await emailFieldProfile.click();
|
|
207
|
+
await testdriver.type("patient@example.com");
|
|
208
|
+
console.log("Filled email address");
|
|
209
|
+
} catch {
|
|
210
|
+
console.log("Email field not found");
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
// Look for and click the save button
|
|
214
|
+
const saveButton = await testdriver.find("Save button or Submit button");
|
|
215
|
+
await saveButton.click();
|
|
216
|
+
console.log("Clicked save button");
|
|
217
|
+
|
|
218
|
+
// Wait for save to complete
|
|
219
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
220
|
+
|
|
221
|
+
// Verify save was successful
|
|
222
|
+
const saveSuccess = await testdriver.assert("changes were saved successfully or save confirmation appears");
|
|
223
|
+
expect(saveSuccess).toBeTruthy();
|
|
224
|
+
} catch (error) {
|
|
225
|
+
console.log("Could not complete patient profile form:", error.message);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
// Take final screenshot
|
|
229
|
+
const finalScreenshot = await testdriver.screenshot();
|
|
230
|
+
expect(finalScreenshot).toBeDefined();
|
|
231
|
+
|
|
232
|
+
console.log("โ
Test completed successfully! Remember to uncomment all checkpoints for final validation.");
|
|
233
|
+
});
|
|
234
|
+
});
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* TestDriver SDK - Console Log Test
|
|
3
|
+
* Tests that console.log statements are captured and sent to dashcam
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { describe, expect, it } from "vitest";
|
|
7
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
8
|
+
|
|
9
|
+
describe("Console Log Test", () => {
|
|
10
|
+
it("should capture console logs and send them to dashcam", async (context) => {
|
|
11
|
+
console.log("๐ฌ Test starting - this should appear in dashcam");
|
|
12
|
+
|
|
13
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
14
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
15
|
+
|
|
16
|
+
console.log("โ
Chrome launched successfully");
|
|
17
|
+
|
|
18
|
+
// Give Chrome a moment to fully render the UI
|
|
19
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
20
|
+
|
|
21
|
+
console.log("๐ Looking for Sign In button");
|
|
22
|
+
|
|
23
|
+
// Find and click the sign in button
|
|
24
|
+
const signInButton = await testdriver.find(
|
|
25
|
+
"Sign In, black button below the password field",
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
console.log("๐ Clicking Sign In button");
|
|
29
|
+
await signInButton.click();
|
|
30
|
+
|
|
31
|
+
console.log("๐งช Asserting error message appears");
|
|
32
|
+
|
|
33
|
+
// Assert error shows
|
|
34
|
+
const result = await testdriver.assert(
|
|
35
|
+
"an error shows that fields are required",
|
|
36
|
+
);
|
|
37
|
+
|
|
38
|
+
console.log("โ
Test completed successfully - all logs should be in dashcam");
|
|
39
|
+
|
|
40
|
+
expect(result).toBeTruthy();
|
|
41
|
+
});
|
|
42
|
+
});
|
|
@@ -1,62 +1,12 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
afterEach,
|
|
4
|
-
beforeAll,
|
|
5
|
-
beforeEach,
|
|
6
|
-
describe,
|
|
7
|
-
expect,
|
|
8
|
-
it,
|
|
9
|
-
} from "vitest";
|
|
10
|
-
import {
|
|
11
|
-
addDashcamLog,
|
|
12
|
-
authDashcam,
|
|
13
|
-
createTestClient,
|
|
14
|
-
launchChrome,
|
|
15
|
-
setupTest,
|
|
16
|
-
startDashcam,
|
|
17
|
-
stopDashcam,
|
|
18
|
-
teardownTest,
|
|
19
|
-
waitForPage,
|
|
20
|
-
} from "./setup/testHelpers.mjs";
|
|
1
|
+
import { describe, expect, it } from "vitest";
|
|
2
|
+
import { TestDriver } from "../../src/vitest/hooks.mjs";
|
|
21
3
|
|
|
22
|
-
describe
|
|
23
|
-
|
|
4
|
+
describe("Type Test", () => {
|
|
5
|
+
it("should enter standard_user in username field", async (context) => {
|
|
6
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
7
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
24
8
|
|
|
25
|
-
|
|
26
|
-
testdriver = createTestClient({ task: { id: "type-test-suite" } });
|
|
27
|
-
await setupTest(testdriver, { prerun: false }); // Skip prerun, we'll handle dashcam manually
|
|
28
|
-
|
|
29
|
-
// One-time dashcam setup (auth and add logs)
|
|
30
|
-
await authDashcam(testdriver);
|
|
31
|
-
await addDashcamLog(testdriver);
|
|
32
|
-
await launchChrome(testdriver);
|
|
33
|
-
await waitForPage(testdriver, "TestDriver.ai Sandbox");
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
beforeEach(async () => {
|
|
37
|
-
await startDashcam(testdriver);
|
|
38
|
-
}, 60000);
|
|
39
|
-
|
|
40
|
-
afterEach(async (context) => {
|
|
41
|
-
// Stop dashcam first to get the URL
|
|
42
|
-
const dashcamUrl = await stopDashcam(testdriver);
|
|
43
|
-
console.log("๐ค Dashcam URL:", dashcamUrl);
|
|
44
|
-
|
|
45
|
-
// Use teardownTest to track results, but skip postrun (already stopped dashcam) and disconnect
|
|
46
|
-
await teardownTest(testdriver, {
|
|
47
|
-
task: context.task,
|
|
48
|
-
dashcamUrl: dashcamUrl, // Pass the dashcam URL we already got
|
|
49
|
-
postrun: false, // Skip postrun since we manually stopped dashcam
|
|
50
|
-
disconnect: false, // Don't disconnect, we'll do that in afterAll
|
|
51
|
-
});
|
|
52
|
-
});
|
|
53
|
-
|
|
54
|
-
afterAll(async () => {
|
|
55
|
-
await testdriver.disconnect();
|
|
56
|
-
});
|
|
57
|
-
|
|
58
|
-
it("should enter standard_user in username field", async () => {
|
|
59
|
-
await testdriver.focusApplication("Google Chrome");
|
|
9
|
+
//
|
|
60
10
|
const usernameField = await testdriver.find(
|
|
61
11
|
"Username, input field for username",
|
|
62
12
|
);
|
|
@@ -69,7 +19,18 @@ describe.sequential("Type Test", () => {
|
|
|
69
19
|
expect(result).toBeTruthy();
|
|
70
20
|
});
|
|
71
21
|
|
|
72
|
-
it("should show validation message when clicking Sign In without password", async () => {
|
|
22
|
+
it("should show validation message when clicking Sign In without password", async (context) => {
|
|
23
|
+
const testdriver = TestDriver(context, { headless: true });
|
|
24
|
+
await testdriver.provision.chrome({ url: 'http://testdriver-sandbox.vercel.app/login' });
|
|
25
|
+
|
|
26
|
+
// First fill in username
|
|
27
|
+
const usernameField = await testdriver.find(
|
|
28
|
+
"Username, input field for username",
|
|
29
|
+
);
|
|
30
|
+
await usernameField.click();
|
|
31
|
+
await testdriver.type("standard_user");
|
|
32
|
+
|
|
33
|
+
//
|
|
73
34
|
const signInButton = await testdriver.find(
|
|
74
35
|
"Sign in, black button below the password field",
|
|
75
36
|
);
|
package/vitest.config.mjs
CHANGED