@take-out/docs 0.0.42
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/aggregates.md +584 -0
- package/cloudflare-dev-tunnel.md +41 -0
- package/database.md +229 -0
- package/docs.md +8 -0
- package/emitters.md +562 -0
- package/hot-updater.md +223 -0
- package/native-hot-update.md +252 -0
- package/one-components.md +234 -0
- package/one-hooks.md +570 -0
- package/one-routes.md +660 -0
- package/package-json.md +115 -0
- package/package.json +12 -0
- package/react-native-navigation-flow.md +184 -0
- package/scripts.md +147 -0
- package/sync-prompt.md +208 -0
- package/tamagui.md +478 -0
- package/testing-integration.md +564 -0
- package/triggers.md +450 -0
- package/xcodebuild-mcp.md +127 -0
- package/zero.md +719 -0
|
@@ -0,0 +1,564 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: testing-integration
|
|
3
|
+
description: Integration testing guide. Use when writing Playwright tests, running bun test:integration, testing with loginAsDemo, or debugging test failures. INVOKE WHEN: integration tests, e2e tests, end-to-end, Playwright, browser tests, test:integration, test fixtures, test setup, test users.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Integration Testing Guide
|
|
7
|
+
|
|
8
|
+
This guide covers integration testing setup, best practices, and troubleshooting
|
|
9
|
+
for the chat application. Integration tests verify that different parts of the
|
|
10
|
+
system work together correctly, from the UI through the API to the database.
|
|
11
|
+
|
|
12
|
+
## Quick Start
|
|
13
|
+
|
|
14
|
+
### Running Integration Tests Locally
|
|
15
|
+
|
|
16
|
+
For easy development integration testing, use the unified command:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
# starts both dev web server and backend services in one command
|
|
20
|
+
bun ci:start-dev
|
|
21
|
+
|
|
22
|
+
# in another terminal, run all integration tests
|
|
23
|
+
bun test:integration
|
|
24
|
+
|
|
25
|
+
# or run a specific test file
|
|
26
|
+
bun test:integration src/integration/search.test.ts
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
You can also run in production mode (like CI does) if you've run `bun web:build`
|
|
30
|
+
first:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
bun web:build
|
|
34
|
+
bun ci:start-prod
|
|
35
|
+
|
|
36
|
+
# in another terminal, run tests
|
|
37
|
+
bun test:integration
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Important: Database State Management
|
|
41
|
+
|
|
42
|
+
Always restart `bun ci:start-dev` between test runs to ensure a clean database
|
|
43
|
+
state. This is critical because:
|
|
44
|
+
|
|
45
|
+
- Tests may create data that persists between runs
|
|
46
|
+
- Search tests in particular can fail if old test messages remain in the
|
|
47
|
+
database
|
|
48
|
+
- The database accumulates test data with each run if not restarted
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
# if tests fail or behave unexpectedly:
|
|
52
|
+
1. Stop ci:start-dev (Ctrl+C)
|
|
53
|
+
2. Run `bun ci:start-dev` again to get a fresh database
|
|
54
|
+
3. Run your tests
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Architecture Overview
|
|
58
|
+
|
|
59
|
+
### Test Stack
|
|
60
|
+
|
|
61
|
+
- Framework: Playwright Test
|
|
62
|
+
- Database: PostgreSQL with pgvector extension
|
|
63
|
+
- Real-time: Zero sync system
|
|
64
|
+
- Auth: Better Auth with test admin user
|
|
65
|
+
- Search: pgvector for semantic search
|
|
66
|
+
- Browser: Chromium (automatically installed)
|
|
67
|
+
|
|
68
|
+
### Directory Structure
|
|
69
|
+
|
|
70
|
+
```
|
|
71
|
+
src/integration/
|
|
72
|
+
├── .output/ # test results and traces
|
|
73
|
+
├── global-setup.ts # global test setup
|
|
74
|
+
├── helpers.ts # shared helper functions
|
|
75
|
+
├── api.test.ts # api integration tests
|
|
76
|
+
├── basic.test.ts # basic app functionality
|
|
77
|
+
├── chat-api.test.ts # chat api tests
|
|
78
|
+
├── embeddings.test.ts # embeddings and vector search
|
|
79
|
+
├── search.test.ts # search functionality
|
|
80
|
+
└── private-chat-stats.test.ts
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
## Test Infrastructure
|
|
84
|
+
|
|
85
|
+
### Playwright Configuration
|
|
86
|
+
|
|
87
|
+
The test configuration is defined in `playwright.config.ts`:
|
|
88
|
+
|
|
89
|
+
```typescript
|
|
90
|
+
export default defineConfig({
|
|
91
|
+
testDir: './src/integration',
|
|
92
|
+
outputDir: './src/integration/.output/test-results',
|
|
93
|
+
globalSetup: './src/integration/global-setup.ts',
|
|
94
|
+
timeout: 30 * 1000,
|
|
95
|
+
expect: {
|
|
96
|
+
timeout: 5000,
|
|
97
|
+
},
|
|
98
|
+
fullyParallel: false,
|
|
99
|
+
retries: process.env.CI ? 1 : 0,
|
|
100
|
+
workers: process.env.CI ? 1 : undefined,
|
|
101
|
+
reporter: process.env.CI ? 'dot' : 'line',
|
|
102
|
+
use: {
|
|
103
|
+
baseURL: 'http://localhost:8081',
|
|
104
|
+
trace: 'on-first-retry',
|
|
105
|
+
},
|
|
106
|
+
projects: [
|
|
107
|
+
{
|
|
108
|
+
name: 'chromium',
|
|
109
|
+
use: { ...devices['Desktop Chrome'] },
|
|
110
|
+
},
|
|
111
|
+
],
|
|
112
|
+
})
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
### Global Setup
|
|
116
|
+
|
|
117
|
+
The global setup (`global-setup.ts`) runs once before all tests:
|
|
118
|
+
|
|
119
|
+
1. Launches a browser instance
|
|
120
|
+
2. Logs in as admin user
|
|
121
|
+
3. Creates a Tamagui test server
|
|
122
|
+
4. Sets up initial test environment
|
|
123
|
+
|
|
124
|
+
This ensures a consistent starting state for all tests.
|
|
125
|
+
|
|
126
|
+
## Writing Integration Tests
|
|
127
|
+
|
|
128
|
+
### Basic Test Structure
|
|
129
|
+
|
|
130
|
+
```typescript
|
|
131
|
+
import { test, expect } from '@playwright/test'
|
|
132
|
+
|
|
133
|
+
test.describe('Feature Name', () => {
|
|
134
|
+
test.beforeAll(async ({ browser }) => {
|
|
135
|
+
// setup that runs once before all tests in this suite
|
|
136
|
+
})
|
|
137
|
+
|
|
138
|
+
test.beforeEach(async ({ page }) => {
|
|
139
|
+
// setup that runs before each test
|
|
140
|
+
await page.goto('/tamagui')
|
|
141
|
+
})
|
|
142
|
+
|
|
143
|
+
test('should do something', async ({ page }) => {
|
|
144
|
+
await expect(page.locator('[data-testid="element"]')).toBeVisible()
|
|
145
|
+
})
|
|
146
|
+
|
|
147
|
+
test.afterEach(async ({ page }) => {
|
|
148
|
+
// cleanup after each test
|
|
149
|
+
})
|
|
150
|
+
})
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
### Using Data Test IDs
|
|
154
|
+
|
|
155
|
+
Always use `data-testid` attributes for reliable element selection:
|
|
156
|
+
|
|
157
|
+
```typescript
|
|
158
|
+
// good - uses test ID
|
|
159
|
+
const button = page.locator('[data-testid="submit-button"]')
|
|
160
|
+
|
|
161
|
+
// avoid - fragile selector
|
|
162
|
+
const button = page.locator('button.submit')
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Waiting for Elements
|
|
166
|
+
|
|
167
|
+
Use proper wait strategies for async operations:
|
|
168
|
+
|
|
169
|
+
```typescript
|
|
170
|
+
// wait for element to be visible
|
|
171
|
+
await page.waitForSelector('[data-testid="message-list"]', {
|
|
172
|
+
state: 'visible',
|
|
173
|
+
timeout: 5000,
|
|
174
|
+
})
|
|
175
|
+
|
|
176
|
+
// wait for network idle
|
|
177
|
+
await page.goto(url, { waitUntil: 'networkidle' })
|
|
178
|
+
|
|
179
|
+
// wait for specific time (use sparingly)
|
|
180
|
+
await page.waitForTimeout(800)
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
## Database State Management
|
|
184
|
+
|
|
185
|
+
### Clean Database Requirements
|
|
186
|
+
|
|
187
|
+
Integration tests require a clean database state. This is managed through:
|
|
188
|
+
|
|
189
|
+
1. Docker Compose: Spins up fresh PostgreSQL with pgvector
|
|
190
|
+
2. Migrations: Automatically applied on startup
|
|
191
|
+
3. Test Data: Created by individual tests as needed
|
|
192
|
+
|
|
193
|
+
### Database Reset Strategy
|
|
194
|
+
|
|
195
|
+
```bash
|
|
196
|
+
# manual database reset
|
|
197
|
+
docker compose down
|
|
198
|
+
docker compose up -d
|
|
199
|
+
bun db:migrate
|
|
200
|
+
|
|
201
|
+
# or simply restart the development environment
|
|
202
|
+
bun ci:start-dev
|
|
203
|
+
```
|
|
204
|
+
|
|
205
|
+
### Test Data Isolation
|
|
206
|
+
|
|
207
|
+
Use unique identifiers to prevent data collision:
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
test('create and search for message', async ({ page }) => {
|
|
211
|
+
const uniqueMessage = `Test message ${Date.now()}`
|
|
212
|
+
await writeMessageInChannel(page, uniqueMessage)
|
|
213
|
+
})
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
## Common Test Patterns
|
|
217
|
+
|
|
218
|
+
### Search Tests
|
|
219
|
+
|
|
220
|
+
```typescript
|
|
221
|
+
test('search for messages', async ({ page }) => {
|
|
222
|
+
const testMessage = `Search test ${Date.now()}`
|
|
223
|
+
await writeMessageInChannel(page, testMessage)
|
|
224
|
+
|
|
225
|
+
await page.waitForTimeout(800) // wait for indexing
|
|
226
|
+
|
|
227
|
+
await page.keyboard.press('Meta+f')
|
|
228
|
+
await page.keyboard.type('search test')
|
|
229
|
+
|
|
230
|
+
const results = page.locator('.message-item-minimal')
|
|
231
|
+
await expect(results).toHaveCount(1)
|
|
232
|
+
})
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
### Real-time Updates
|
|
236
|
+
|
|
237
|
+
```typescript
|
|
238
|
+
test('real-time message sync', async ({ page, context }) => {
|
|
239
|
+
const page2 = await context.newPage()
|
|
240
|
+
await page2.goto('/tamagui')
|
|
241
|
+
|
|
242
|
+
await writeMessageInChannel(page, 'Real-time test')
|
|
243
|
+
|
|
244
|
+
await expect(page2.locator('text="Real-time test"')).toBeVisible({
|
|
245
|
+
timeout: 2000,
|
|
246
|
+
})
|
|
247
|
+
})
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
### API Integration Tests
|
|
251
|
+
|
|
252
|
+
```typescript
|
|
253
|
+
test('API endpoint', async ({ request }) => {
|
|
254
|
+
const response = await request.post('/api/messages', {
|
|
255
|
+
data: {
|
|
256
|
+
content: 'API test message',
|
|
257
|
+
channelId: 'test-channel',
|
|
258
|
+
},
|
|
259
|
+
})
|
|
260
|
+
|
|
261
|
+
expect(response.ok()).toBeTruthy()
|
|
262
|
+
const json = await response.json()
|
|
263
|
+
expect(json.success).toBe(true)
|
|
264
|
+
})
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
## Helper Functions
|
|
268
|
+
|
|
269
|
+
The `helpers.ts` file provides reusable functions:
|
|
270
|
+
|
|
271
|
+
### Core Helpers
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
await finishOnboarding(page)
|
|
275
|
+
await setupTamaguiServer(page)
|
|
276
|
+
await writeMessageInChannel(page, 'Hello world')
|
|
277
|
+
await expectMessageInChannel(page, 'Hello world')
|
|
278
|
+
await openHUD(page)
|
|
279
|
+
await focusChannelInput(page)
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Visibility Helpers
|
|
283
|
+
|
|
284
|
+
```typescript
|
|
285
|
+
await expectToBeVisible(locator, { timeout: 2000 })
|
|
286
|
+
await expectToBeHidden(locator, { timeout: 2000 })
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
## CI/CD Integration
|
|
290
|
+
|
|
291
|
+
### GitHub Actions Workflow
|
|
292
|
+
|
|
293
|
+
Integration tests run automatically in CI:
|
|
294
|
+
|
|
295
|
+
```yaml
|
|
296
|
+
- name: Install Playwright
|
|
297
|
+
run: bunx playwright install --with-deps chromium
|
|
298
|
+
|
|
299
|
+
- name: Start backend services
|
|
300
|
+
run: bun ci:backend &
|
|
301
|
+
|
|
302
|
+
- name: Start frontend (production)
|
|
303
|
+
run: bun ci:frontend &
|
|
304
|
+
|
|
305
|
+
- name: Wait for server
|
|
306
|
+
run: bun wait-for-server
|
|
307
|
+
|
|
308
|
+
- name: Run integration tests
|
|
309
|
+
run: bun test:integration
|
|
310
|
+
```
|
|
311
|
+
|
|
312
|
+
### CI-Specific Configuration
|
|
313
|
+
|
|
314
|
+
The CI environment has specific settings:
|
|
315
|
+
|
|
316
|
+
- Retries: 1 retry on failure
|
|
317
|
+
- Workers: Single worker for consistency
|
|
318
|
+
- Reporter: Dot reporter for compact output
|
|
319
|
+
- Timeout: Extended timeouts for slower CI machines
|
|
320
|
+
|
|
321
|
+
### Testing Everything in Production Mode
|
|
322
|
+
|
|
323
|
+
This is not often needed when developing but may be useful to test things fully
|
|
324
|
+
end-to-end:
|
|
325
|
+
|
|
326
|
+
```bash
|
|
327
|
+
# run the full CI setup except for deploying at the end
|
|
328
|
+
bun run ci --skip-deploy
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
### Running Tests with Different Configurations
|
|
332
|
+
|
|
333
|
+
```bash
|
|
334
|
+
# run with specific skips
|
|
335
|
+
bun run ci --skip-tests --skip-deploy
|
|
336
|
+
|
|
337
|
+
# just run tests in CI mode
|
|
338
|
+
CI=true bun test:integration
|
|
339
|
+
```
|
|
340
|
+
|
|
341
|
+
## Troubleshooting
|
|
342
|
+
|
|
343
|
+
### Common Issues and Solutions
|
|
344
|
+
|
|
345
|
+
#### ERR_JWKS_NO_MATCHING_KEY
|
|
346
|
+
|
|
347
|
+
Problem: Authentication keys mismatch
|
|
348
|
+
|
|
349
|
+
Solution:
|
|
350
|
+
|
|
351
|
+
```bash
|
|
352
|
+
# restart services to regenerate keys
|
|
353
|
+
bun ci:start-dev
|
|
354
|
+
|
|
355
|
+
# clear browser storage if the issue persists
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
#### Tests Finding Unexpected Data
|
|
359
|
+
|
|
360
|
+
Problem: Old test data affecting new runs
|
|
361
|
+
|
|
362
|
+
Solution:
|
|
363
|
+
|
|
364
|
+
```bash
|
|
365
|
+
Ctrl+C # stop ci:start-dev
|
|
366
|
+
bun ci:start-dev # fresh start
|
|
367
|
+
bun test:integration
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
#### Search Tests Failing
|
|
371
|
+
|
|
372
|
+
Problem: Search results not as expected
|
|
373
|
+
|
|
374
|
+
Solution:
|
|
375
|
+
|
|
376
|
+
```typescript
|
|
377
|
+
// ensure sufficient wait time for indexing
|
|
378
|
+
await page.waitForTimeout(800)
|
|
379
|
+
|
|
380
|
+
// add debug logging
|
|
381
|
+
const count = await results.count()
|
|
382
|
+
if (count !== expected) {
|
|
383
|
+
for (let i = 0; i < count; i++) {
|
|
384
|
+
const text = await results.nth(i).textContent()
|
|
385
|
+
console.info(`Result ${i}: ${text}`)
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
#### Port 8081 Already in Use
|
|
391
|
+
|
|
392
|
+
Problem: Previous test run didn't clean up
|
|
393
|
+
|
|
394
|
+
Solution:
|
|
395
|
+
|
|
396
|
+
```bash
|
|
397
|
+
lsof -i :8081
|
|
398
|
+
kill -9 <PID>
|
|
399
|
+
|
|
400
|
+
# or use docker cleanup
|
|
401
|
+
docker compose down
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
#### Playwright Installation Issues
|
|
405
|
+
|
|
406
|
+
Problem: Browser binaries not installed
|
|
407
|
+
|
|
408
|
+
Solution:
|
|
409
|
+
|
|
410
|
+
```bash
|
|
411
|
+
bunx playwright install --with-deps chromium
|
|
412
|
+
# or install all browsers
|
|
413
|
+
bunx playwright install
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
### Debug Techniques
|
|
417
|
+
|
|
418
|
+
#### Enable Playwright Inspector
|
|
419
|
+
|
|
420
|
+
```bash
|
|
421
|
+
PWDEBUG=1 bun test:integration --headed
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
#### Add Console Logging
|
|
425
|
+
|
|
426
|
+
```typescript
|
|
427
|
+
test('debug test', async ({ page }) => {
|
|
428
|
+
page.on('console', (msg) => {
|
|
429
|
+
console.info('Browser console:', msg.text())
|
|
430
|
+
})
|
|
431
|
+
|
|
432
|
+
page.on('pageerror', (error) => {
|
|
433
|
+
console.error('Page error:', error)
|
|
434
|
+
})
|
|
435
|
+
})
|
|
436
|
+
```
|
|
437
|
+
|
|
438
|
+
#### Save Test Traces
|
|
439
|
+
|
|
440
|
+
```typescript
|
|
441
|
+
test.use({
|
|
442
|
+
trace: 'on',
|
|
443
|
+
video: 'on',
|
|
444
|
+
screenshot: 'on',
|
|
445
|
+
})
|
|
446
|
+
```
|
|
447
|
+
|
|
448
|
+
View traces:
|
|
449
|
+
|
|
450
|
+
```bash
|
|
451
|
+
bunx playwright show-trace src/integration/.output/test-results/*/trace.zip
|
|
452
|
+
```
|
|
453
|
+
|
|
454
|
+
## Best Practices
|
|
455
|
+
|
|
456
|
+
1. Use Unique Test Data: Always include unique identifiers to avoid conflicts
|
|
457
|
+
2. Clean State Assumption: Never assume data from previous tests
|
|
458
|
+
3. Proper Waits: Use appropriate wait strategies
|
|
459
|
+
4. Descriptive Test Names: Write clear, descriptive test names
|
|
460
|
+
5. Isolate Test Logic: Keep tests independent and focused
|
|
461
|
+
6. Error Messages: Provide helpful error context
|
|
462
|
+
7. Parallel Test Considerations: Tests run sequentially for database consistency
|
|
463
|
+
8. Performance Considerations: Minimize wait times, reuse page contexts, batch
|
|
464
|
+
assertions
|
|
465
|
+
9. Accessibility Testing: Include accessibility checks
|
|
466
|
+
10. Mobile Testing: Test responsive behavior
|
|
467
|
+
|
|
468
|
+
## Running Specific Tests
|
|
469
|
+
|
|
470
|
+
To run a single test file:
|
|
471
|
+
|
|
472
|
+
```bash
|
|
473
|
+
bun test:integration src/integration/search.test.ts
|
|
474
|
+
```
|
|
475
|
+
|
|
476
|
+
To run tests with debugging output:
|
|
477
|
+
|
|
478
|
+
```bash
|
|
479
|
+
PWDEBUG=1 bun test:integration src/integration/search.test.ts --headed
|
|
480
|
+
```
|
|
481
|
+
|
|
482
|
+
## Advanced Topics
|
|
483
|
+
|
|
484
|
+
### Custom Test Fixtures
|
|
485
|
+
|
|
486
|
+
Create reusable test contexts:
|
|
487
|
+
|
|
488
|
+
```typescript
|
|
489
|
+
import { test as base } from '@playwright/test'
|
|
490
|
+
|
|
491
|
+
export const test = base.extend({
|
|
492
|
+
authenticatedPage: async ({ page }, use) => {
|
|
493
|
+
await loginAsAdmin(page, '/tamagui')
|
|
494
|
+
await use(page)
|
|
495
|
+
},
|
|
496
|
+
})
|
|
497
|
+
|
|
498
|
+
test('admin feature', async ({ authenticatedPage }) => {
|
|
499
|
+
// already logged in as admin
|
|
500
|
+
})
|
|
501
|
+
```
|
|
502
|
+
|
|
503
|
+
### Testing WebSockets
|
|
504
|
+
|
|
505
|
+
Test real-time features:
|
|
506
|
+
|
|
507
|
+
```typescript
|
|
508
|
+
test('websocket connection', async ({ page }) => {
|
|
509
|
+
await page.evaluate(() => {
|
|
510
|
+
return new Promise((resolve) => {
|
|
511
|
+
const ws = new WebSocket('ws://localhost:8081/ws')
|
|
512
|
+
ws.onopen = () => resolve(true)
|
|
513
|
+
})
|
|
514
|
+
})
|
|
515
|
+
})
|
|
516
|
+
```
|
|
517
|
+
|
|
518
|
+
### Performance Testing
|
|
519
|
+
|
|
520
|
+
Measure and assert performance:
|
|
521
|
+
|
|
522
|
+
```typescript
|
|
523
|
+
test('performance metrics', async ({ page }) => {
|
|
524
|
+
const metrics = await page.evaluate(() =>
|
|
525
|
+
JSON.stringify(performance.getEntriesByType('navigation')),
|
|
526
|
+
)
|
|
527
|
+
|
|
528
|
+
const [navigation] = JSON.parse(metrics)
|
|
529
|
+
expect(navigation.loadEventEnd).toBeLessThan(3000)
|
|
530
|
+
})
|
|
531
|
+
```
|
|
532
|
+
|
|
533
|
+
### Visual Regression Testing
|
|
534
|
+
|
|
535
|
+
Compare screenshots:
|
|
536
|
+
|
|
537
|
+
```typescript
|
|
538
|
+
test('visual regression', async ({ page }) => {
|
|
539
|
+
await page.goto('/tamagui')
|
|
540
|
+
await expect(page).toHaveScreenshot('homepage.png', {
|
|
541
|
+
maxDiffPixels: 100,
|
|
542
|
+
})
|
|
543
|
+
})
|
|
544
|
+
```
|
|
545
|
+
|
|
546
|
+
## Conclusion
|
|
547
|
+
|
|
548
|
+
Integration testing is crucial for maintaining application quality. By following
|
|
549
|
+
these guidelines and best practices, you can write reliable, maintainable
|
|
550
|
+
integration tests that catch issues before they reach production.
|
|
551
|
+
|
|
552
|
+
Remember:
|
|
553
|
+
|
|
554
|
+
- Always start with a clean database state
|
|
555
|
+
- Use unique test data to avoid conflicts
|
|
556
|
+
- Leverage helper functions for common operations
|
|
557
|
+
- Debug with traces and console logs when needed
|
|
558
|
+
- Keep tests focused and independent
|
|
559
|
+
|
|
560
|
+
For more information, refer to:
|
|
561
|
+
|
|
562
|
+
- [Playwright Documentation](https://playwright.dev)
|
|
563
|
+
- [Project README](../README.md)
|
|
564
|
+
- [CI/CD Documentation](./ci-cd-guide.md)
|