integratedhub/tests/TROUBLESHOOTING.md
2026-02-14 02:20:19 +00:00

505 lines
10 KiB
Markdown

# E2E Test Troubleshooting
Quick reference for common E2E test issues and solutions.
## Table of Contents
- [Test Failures](#test-failures)
- [Environment Issues](#environment-issues)
- [Browser Issues](#browser-issues)
- [Network Issues](#network-issues)
- [Database Issues](#database-issues)
- [Performance Issues](#performance-issues)
- [CI/CD Issues](#cicd-issues)
## Test Failures
### "Element not found" or "Timeout"
**Symptoms**: Test fails with timeout waiting for element
**Solutions**:
```typescript
// 1. Increase timeout
await page.locator("#element").isVisible({ timeout: 10000 });
// 2. Use conditional check
if (await page.locator("#element").isVisible({ timeout: 5000 })) {
await expect(page.locator("#element")).toBeVisible();
}
// 3. Wait for specific condition
await page.waitForURL("**/dashboard");
await page.waitForSelector("#element", { state: "visible" });
// 4. Wait for navigation
await Promise.all([
page.waitForURL("**/success"),
page.click("button[type='submit']"),
]);
```
**Common Causes**:
- Element hasn't loaded yet
- Page is still redirecting
- Animation in progress
- Element is conditionally rendered
### "Assertion failed"
**Symptoms**: Expect statement fails
**Solutions**:
```typescript
// 1. Add more context
await expect(page.locator("#element"), "Element should be visible")
.toBeVisible();
// 2. Use retry with timeout
await expect(async () => {
const isVisible = await page.locator("#element").isVisible();
expect(isVisible).toBe(true);
}).toPass({ timeout: 10000 });
// 3. Check actual value
const text = await page.locator("#element").textContent();
console.log("Actual text:", text);
```
### "Test is flaky" (passes sometimes, fails sometimes)
**Solutions**:
```bash
# 1. Run test multiple times
npx playwright test --repeat-each=5
# 2. Increase retries in playwright.config.ts
retries: 3
# 3. Disable parallel execution
fullyParallel: false
workers: 1
```
**Common Causes**:
- Race conditions
- Network timing variations
- Database state not reset
- Previous test state leaking
### "Console errors in test"
**Symptoms**: Test reports console errors
**Solutions**:
```typescript
// 1. Filter expected errors
const errors: string[] = [];
page.on("console", (msg) => {
if (msg.type() === "error") {
errors.push(msg.text());
}
});
// After test
const filteredErrors = errors.filter(
(err) => !err.includes("net::ERR_BLOCKED_BY_CLIENT"),
);
expect(filteredErrors.length).toBe(0);
// 2. Fix the actual error in the application
```
## Environment Issues
### "Port 8080 already in use"
**Solutions**:
```bash
# 1. Kill process using port
lsof -ti:8080 | xargs kill -9
# 2. Use different port
PORT=8081 npx playwright test
# 3. Find and kill manually
ps aux | grep "deno task dev"
kill <PID>
```
### "E2E_TEST not recognized"
**Symptoms**: Tests don't bypass OAuth
**Solution**:
```typescript
// Ensure E2E mode is set in beforeEach
test.beforeEach(async ({ page }) => {
await page.addInitScript(() => {
globalThis.localStorage.setItem("E2E_TEST", "true");
});
});
```
### "Environment variables not set"
**Solutions**:
```bash
# 1. Set in shell
export E2E_TEST=true
export PORT=8080
# 2. Set in command
E2E_TEST=true PORT=8081 npx playwright test
# 3. Set in .env file (loaded by deno)
echo "E2E_TEST=true" > .env
echo "PORT=8080" >> .env
```
## Browser Issues
### "Browser not installed"
**Symptoms**: Error about chromium not installed
**Solution**:
```bash
npx playwright install --with-deps chromium
```
### "Browser crashes during test"
**Solutions**:
```bash
# 1. Update browsers
npx playwright install --force --with-deps chromium
# 2. Clear cache
rm -rf ~/.cache/ms-playwright
# 3. Run in headed mode to see crash
npx playwright test --headed
# 4. Check system resources
free -h # Memory
df -h # Disk space
```
### "Browser window too small"
**Solution**:
```typescript
// In playwright.config.ts
use: {
viewport: { width: 1920, height: 1080 },
}
// Or per test
test.use({ viewport: { width: 1920, height: 1080 } });
```
## Network Issues
### "Network request failed"
**Solutions**:
```typescript
// 1. Wait for network idle
await page.waitForLoadState("networkidle");
// 2. Wait for specific response
await page.waitForResponse("**/api/endpoint");
// 3. Handle timeout
try {
await page.goto("/slow-page", { timeout: 60000 });
} catch (error) {
console.log("Page load timeout, continuing...");
}
```
### "CORS errors"
**Symptoms**: Browser blocks requests due to CORS
**Solution**: This is an application issue, not a test issue. Fix CORS in
backend:
```typescript
// Add CORS headers
response.headers.set("Access-Control-Allow-Origin", "*");
```
### "API returns 401/403"
**Solutions**:
```typescript
// 1. Ensure E2E headers are set
await page.goto("/api/endpoint", {
headers: {
"x-e2e-user": "landlord",
},
});
// 2. Check user has permission
const response = await page.request.get("/api/protected", {
headers: {
"x-e2e-user": "admin", // Use admin if landlord lacks permission
},
});
```
## Database Issues
### "Database connection failed"
**Solutions**:
```bash
# 1. Check database is running
docker ps | grep postgres
# or
psql -h localhost -U postgres -c "SELECT 1;"
# 2. Check connection string
echo $POSTGRES_OPTIONS
# 3. Restart database
docker-compose restart postgres
# 4. Check database exists
psql -h localhost -U postgres -l | grep cyberhybridhub
```
### "Test data conflicts"
**Symptoms**: Tests interfere with each other's data
**Solutions**:
```typescript
// 1. Use unique data (add timestamp)
const timestamp = Date.now();
await page.locator('input[name="title"]').fill(`Test ${timestamp}`);
// 2. Clean up after test
test.afterEach(async ({ page }) => {
await page.request.delete("/api/test-data/cleanup", {
headers: { "x-e2e-user": "admin" },
});
});
// 3. Run tests serially
fullyParallel: false;
workers: 1;
```
### "Migration errors"
**Solutions**:
```bash
# 1. Run migrations
deno task db:push
# 2. Reset database (destructive!)
deno task db:reset
# 3. Check migration status
deno task db:status
```
## Performance Issues
### "Tests are too slow"
**Solutions**:
```bash
# 1. Run tests in parallel
npx playwright test --workers=4
# 2. Run only changed tests
npx playwright test --grep="pattern"
# 3. Skip slow tests
test.skip(process.env.CI, "Skipped in CI");
# 4. Use API tests instead of UI
const response = await page.request.get("/api/data");
```
### "Browser uses too much memory"
**Solutions**:
```bash
# 1. Reduce workers
npx playwright test --workers=1
# 2. Close pages after use
await page.close();
# 3. Restart between test runs
npx playwright test --worker=1
```
### "Test startup is slow"
**Solutions**:
```typescript
// 1. Reuse browser context
test.beforeAll(async ({ browser }) => {
context = await browser.newContext();
});
// 2. Use storage state (save/load cookies)
await context.storageState({ path: "state.json" });
// 3. Reduce timeout in config
timeout: 30000, // reduce from 60000
```
## CI/CD Issues
### "Tests pass locally but fail in CI"
**Solutions**:
```typescript
// 1. Increase retries in CI
retries: process.env.CI ? 2 : 0;
// 2. Increase timeouts in CI
timeout: process.env.CI ? 120000 : 60000;
// 3. Disable parallel in CI
fullyParallel: !process.env.CI;
// 4. Wait longer in tests
await page.waitForTimeout(process.env.CI ? 2000 : 1000);
```
### "CI runner out of disk space"
**Solutions**:
```yaml
# .github/workflows/e2e-tests.yml
- name: Clean up disk space
run: |
sudo rm -rf /usr/local/lib/android
sudo rm -rf /usr/share/dotnet
df -h
```
### "Artifacts not uploaded"
**Solutions**:
```yaml
# Ensure artifact upload step runs even on failure
- name: Upload artifacts
if: always() # Important!
uses: actions/upload-artifact@v4
```
### "Tests timeout in CI"
**Solutions**:
```yaml
# Increase job timeout
- name: Run tests
timeout-minutes: 60 # Increase from default 35
run: npx playwright test
```
## Debugging Tips
### Enable verbose logging
```bash
# Playwright verbose mode
DEBUG=pw:* npx playwright test
# Deno verbose mode
DENO_LOG=INFO npx playwright test
```
### Take screenshots manually
```typescript
await page.screenshot({
path: "debug-screenshot.png",
fullPage: true,
});
```
### Pause test execution
```typescript
// Add pause to inspect state
await page.pause();
```
### Log page state
```typescript
console.log("URL:", page.url());
console.log("Title:", await page.title());
console.log("Content:", await page.content());
```
### Check network requests
```typescript
page.on("request", (request) => {
console.log("Request:", request.url());
});
page.on("response", (response) => {
console.log("Response:", response.url(), response.status());
});
```
## Getting Help
If none of these solutions work:
1. Check [Playwright documentation](https://playwright.dev/docs/debug)
2. Review test output in `test-results/`
3. Open trace file: `npx playwright show-trace test-results/trace.zip`
4. Run in debug mode: `npx playwright test --debug`
5. Check GitHub issues for similar problems
6. Consult [E2E_TEST_GUIDE.md](./E2E_TEST_GUIDE.md)
## Common Error Messages
| Error | Cause | Solution |
| ---------------------------------- | ----------------------- | --------------------------------------- |
| `Test timeout of 60000ms exceeded` | Test took too long | Increase timeout or optimize test |
| `Target closed` | Browser crashed | Check system resources, restart browser |
| `Failed to find element` | Element not in DOM | Use waitForSelector, check selector |
| `Strict mode violation` | Multiple elements match | Use `first()` or more specific selector |
| `net::ERR_CONNECTION_REFUSED` | Server not running | Start dev server, check port |
| `401 Unauthorized` | Not authenticated | Set E2E headers properly |
| `404 Not Found` | Route doesn't exist | Check URL, verify route exists |
| `500 Internal Server Error` | Server error | Check server logs, fix bug |