Skip to content

Debugging

When browser tests fail in CI, debugging can be challenging. This page covers strategies for capturing failure information.

Screenshot Artifacts

Capture screenshots on test failure and upload them as artifacts:

Upload Snippet

yaml
- name: Upload screenshots on failure
  if: failure()
  uses: actions/upload-artifact@v4
  with:
    name: browser-screenshots
    path: backend/tests/Browser/screenshots/
    retention-days: 7

Taking Screenshots in Tests

php
test('user can login', function () {
    $this->bridge('/login')
        ->typeSlowly('[data-testid="email"]', 'test@example.com', 20)
        ->typeSlowly('[data-testid="password"]', 'password', 20)
        ->click('[data-testid="submit"]')
        ->screenshot('after-login-click')  // Saved to tests/Browser/screenshots/
        ->assertPathContains('/dashboard');
});

Downloading Artifacts

After a failed run:

  1. Go to the workflow run page
  2. Scroll to "Artifacts" section
  3. Download browser-screenshots

HTML Snapshots

Capture page HTML for debugging:

php
test('page renders correctly', function () {
    $this->bridge('/dashboard')
        ->storeHtml('dashboard-page')  // Saved to tests/Browser/html/
        ->assertVisible('[data-testid="stats"]');
});
yaml
- name: Upload HTML snapshots on failure
  if: failure()
  uses: actions/upload-artifact@v4
  with:
    name: browser-html
    path: backend/tests/Browser/html/
    retention-days: 7

Console Logs

Capture browser console logs:

php
test('no console errors', function () {
    $this->bridge('/dashboard')
        ->storeConsoleLog('dashboard-console')
        ->assertVisible('[data-testid="content"]');
});

Common CI Failures

1. Frontend Server Not Starting

Symptom: Tests timeout waiting for frontend

Debug:

yaml
- name: Check frontend directory
  run: ls -la frontend/

- name: Check frontend package.json
  run: cat frontend/package.json

Solutions:

  • Verify cwd path matches checkout location
  • Check npm ci completed successfully
  • Ensure package.json has a dev script

2. Database Not Visible

Symptom: Tests create data but API returns empty

Debug:

yaml
- name: Check database
  run: |
    php artisan tinker --execute="echo \App\Models\User::count();"

Solutions:

  • Use DatabaseTruncation instead of RefreshDatabase
  • Use file-based SQLite, not :memory:
  • Check phpunit.xml has correct DB_DATABASE

3. Port Conflicts

Symptom: "Port already in use" errors

Solution: The plugin uses dynamic port discovery. Don't hardcode ports.

4. Playwright Browser Missing

Symptom: "Executable doesn't exist" or browser launch failures

Debug:

yaml
- name: List Playwright browsers
  run: npx playwright install --dry-run

Solution: Ensure installation order:

yaml
- run: npm ci
- run: npx playwright install --with-deps chromium

5. Timeout Issues

Symptom: Tests pass locally but timeout in CI

Solutions:

php
// Increase wait times
$this->bridge('/slow-page')
    ->waitForEvent('networkidle')  // Wait for network
    ->wait(2)                       // Extra buffer
    ->assertVisible('[data-testid="content"]');
yaml
# Increase job timeout
- name: Run browser tests
  run: ./vendor/bin/pest tests/Browser
  timeout-minutes: 30

Local Reproduction

To reproduce CI failures locally:

bash
# Match CI environment
export APP_ENV=testing
export DB_CONNECTION=sqlite
export DB_DATABASE=database/database.sqlite

# Run same commands
touch database/database.sqlite
php artisan migrate:fresh
./vendor/bin/pest tests/Browser

Verbose Output

Run tests with more output:

yaml
- name: Run browser tests
  run: ./vendor/bin/pest tests/Browser -v

Complete Debugging Workflow

yaml
name: Browser Tests

on: [push, pull_request]

jobs:
  browser-tests:
    runs-on: ubuntu-latest
    defaults:
      run:
        working-directory: backend

    steps:
      - name: Checkout API
        uses: actions/checkout@v4
        with:
          path: backend

      - name: Checkout Frontend
        uses: actions/checkout@v4
        with:
          repository: your-org/frontend-repo
          path: frontend

      # ... setup steps ...

      - name: Run browser tests
        run: ./vendor/bin/pest tests/Browser -v

      - name: Upload screenshots on failure
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: browser-screenshots
          path: backend/tests/Browser/screenshots/
          retention-days: 7

      - name: Upload HTML snapshots on failure
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: browser-html
          path: backend/tests/Browser/html/
          retention-days: 7

      - name: Upload test logs on failure
        if: failure()
        uses: actions/upload-artifact@v4
        with:
          name: test-logs
          path: backend/storage/logs/
          retention-days: 7

Released under the MIT License.