---
description: Frontend testing standards using Playwright for end-to-end testing
globs: **/*.{ts,js,svelte}
---
<rule>
When working on frontend features:

1. Test Coverage Requirements:
   - All new features must have e2e tests
   - Critical user flows must be tested
   - Test both success and error paths
   - Test responsive behavior for mobile/desktop
   - Test accessibility where applicable

2. Test Structure:
   - Use descriptive test names
   - Reset database state before each test
   - Group related tests in describe blocks
   - Keep tests focused and atomic
   - Add explicit waits and checks at key points

3. Testing Best Practices:
   - Test user interactions, not implementation
   - Use data-testid for test-specific selectors
   - Test across different viewport sizes
   - Test across multiple browsers
   - Verify visual and functional aspects

4. Reliable Test Execution:
   - Always reset database state with `/api/test/reset`
   - Wait for redirects with URL checks
   - Wait for content with `.waitForSelector()`
   - Check element visibility before interaction
   - Use specific selectors (id, role, exact text)
   - Add explicit waits after state changes
   - Store URLs after navigation for reliable returns

5. Required Test Cases:
   - Navigation flows
   - Form submissions
   - Error handling
   - Loading states
   - Responsive behavior
   - Cross-browser compatibility

6. Database Considerations:
   - Use single worker mode due to shared database
   - Reset database state before each test
   - Avoid parallel test execution
   - Consider test isolation needs

7. Running Tests:
   - Run tests before committing: `bun test`
   - Debug tests with UI: `bun test:ui`
   - Debug specific test: `bun test:debug`
   - Install browsers: `bun test:install`

metadata:
  priority: high
  version: 1.1
</rule>

examples:
  - input: |
      # Bad: Unreliable waiting
      await page.click('button');
      await page.locator('h1').textContent();
    output: |
      # Good: Explicit waits and checks
      await page.click('button');
      await expect(page).toHaveURL(/\/expected-path/);
      await page.waitForSelector('h1');
      await expect(page.locator('h1')).toBeVisible();

  - input: |
      # Bad: No state reset
      test('creates item', async ({ page }) => {
        await page.goto('/items/new');
      });
    output: |
      # Good: Reset state first
      test('creates item', async ({ page }) => {
        await page.goto('/');
        await page.request.post('/api/test/reset');
        await page.goto('/items/new');
      });

  - input: |
      # Bad: No tests for new feature
      git commit -m "feat: add note search"
    output: |
      # Good: Feature with tests
      bun test
      git commit -m "feat: add note search with e2e tests
      
      Tests added:
      - Search functionality
      - Empty results handling
      - Error states
      - Mobile layout"

  - input: |
      # Bad: Testing implementation details
      test('internal state is correct', () => {
        expect(component.state.value).toBe(true)
      })
    output: |
      # Good: Testing user interaction
      test('user can toggle feature', async ({ page }) => {
        await page.click('[data-testid=toggle]')
        await expect(page.locator('.status')).toHaveText('Enabled')
      })