Files
michaelschiemer/tests/e2e/livecomponent/README.md
Michael Schiemer fc3d7e6357 feat(Production): Complete production deployment infrastructure
- Add comprehensive health check system with multiple endpoints
- Add Prometheus metrics endpoint
- Add production logging configurations (5 strategies)
- Add complete deployment documentation suite:
  * QUICKSTART.md - 30-minute deployment guide
  * DEPLOYMENT_CHECKLIST.md - Printable verification checklist
  * DEPLOYMENT_WORKFLOW.md - Complete deployment lifecycle
  * PRODUCTION_DEPLOYMENT.md - Comprehensive technical reference
  * production-logging.md - Logging configuration guide
  * ANSIBLE_DEPLOYMENT.md - Infrastructure as Code automation
  * README.md - Navigation hub
  * DEPLOYMENT_SUMMARY.md - Executive summary
- Add deployment scripts and automation
- Add DEPLOYMENT_PLAN.md - Concrete plan for immediate deployment
- Update README with production-ready features

All production infrastructure is now complete and ready for deployment.
2025-10-25 19:18:37 +02:00

8.5 KiB

LiveComponent E2E Tests

End-to-End tests for LiveComponent system functionality.

Prerequisites

E2E tests require:

  • Running development server (npm run dev)
  • Test components deployed at test URLs
  • Playwright or similar E2E testing framework

Test Setup

npm install --save-dev @playwright/test
npx playwright install

Option 2: Puppeteer

npm install --save-dev puppeteer jest-puppeteer

Planned E2E Test Suites

Fragment Updates E2E Tests

File: FragmentUpdates.e2e.test.js

Test Scenarios:

  1. Single Fragment Update

    • Load component with multiple fragments
    • Trigger action that updates single fragment
    • Verify only target fragment updated
    • Verify other fragments unchanged
    • Verify focus preserved
  2. Multiple Fragment Updates

    • Trigger action with data-lc-fragments="frag1,frag2"
    • Verify both fragments updated
    • Verify unused fragments unchanged
    • Measure DOM mutation count
  3. Fragment Update with Events

    • Update fragment that dispatches events
    • Verify event received by listeners
    • Verify event payload correct
  4. Nested Fragment Updates

    • Update parent fragment containing child fragments
    • Verify proper nested patching
    • Verify no child components destroyed
  5. Fragment Update Performance

    • Measure time for fragment update vs full render
    • Verify 70-95% DOM operation reduction
    • Measure bandwidth difference (60-90% reduction)

Example Implementation:

describe('Fragment Updates E2E', () => {
    beforeEach(async () => {
        await page.goto('http://localhost:5173/live-component/demo');
    });

    test('updates single fragment without affecting others', async () => {
        // Find component
        const component = await page.$('[data-live-component="user-stats:1"]');

        // Get initial fragment contents
        const initialHeader = await component.$eval(
            '[data-lc-fragment="header"]',
            el => el.textContent
        );
        const initialStats = await component.$eval(
            '[data-lc-fragment="stats"]',
            el => el.textContent
        );

        // Trigger action that updates only stats fragment
        await component.$eval(
            '[data-live-action="refreshStats"][data-lc-fragments="stats"]',
            btn => btn.click()
        );

        // Wait for update
        await page.waitForTimeout(100);

        // Verify stats updated
        const newStats = await component.$eval(
            '[data-lc-fragment="stats"]',
            el => el.textContent
        );
        expect(newStats).not.toBe(initialStats);

        // Verify header unchanged
        const newHeader = await component.$eval(
            '[data-lc-fragment="header"]',
            el => el.textContent
        );
        expect(newHeader).toBe(initialHeader);
    });

    test('preserves focus during fragment update', async () => {
        const input = await page.$('[data-live-component] input[name="search"]');

        // Focus input and type
        await input.focus();
        await input.type('test query');

        // Trigger fragment update
        await page.click('[data-live-action="search"][data-lc-fragments="results"]');
        await page.waitForTimeout(100);

        // Verify focus preserved
        const focusedElement = await page.evaluate(() => document.activeElement.name);
        expect(focusedElement).toBe('search');

        // Verify selection preserved
        const selectionStart = await input.evaluate(el => el.selectionStart);
        const selectionEnd = await input.evaluate(el => el.selectionEnd);
        expect(selectionStart).toBe(10);
        expect(selectionEnd).toBe(10);
    });
});

Multi-Component Batch Updates E2E Tests

File: BatchUpdates.e2e.test.js

Test Scenarios:

  1. Automatic Batching

    • Queue multiple operations within 50ms window
    • Verify single HTTP request sent
    • Verify all components updated correctly
  2. Manual Batch Execution

    • Execute batch with LiveComponent.executeBatch()
    • Verify all operations processed
    • Verify partial failures handled gracefully
  3. Batch with Fragments

    • Batch multiple fragment updates
    • Verify fragments updated efficiently
    • Measure HTTP request reduction (60-80%)
  4. Batch Performance

    • Compare batch vs individual requests
    • Measure latency reduction
    • Measure bandwidth reduction (~40%)
  5. Batch Error Handling

    • Trigger batch with some invalid operations
    • Verify failed operations reported
    • Verify successful operations still applied
    • Verify error isolation (no cascade failures)

Example Implementation:

describe('Batch Updates E2E', () => {
    beforeEach(async () => {
        await page.goto('http://localhost:5173/live-component/batch-demo');
    });

    test('batches multiple operations automatically', async () => {
        // Monitor network requests
        const requests = [];
        page.on('request', req => {
            if (req.url().includes('/live-component/batch')) {
                requests.push(req);
            }
        });

        // Trigger multiple operations quickly
        await page.evaluate(() => {
            LiveComponent.queueBatchOperation({
                componentId: 'counter:1',
                method: 'increment'
            });
            LiveComponent.queueBatchOperation({
                componentId: 'counter:2',
                method: 'increment'
            });
            LiveComponent.queueBatchOperation({
                componentId: 'counter:3',
                method: 'increment'
            });
        });

        // Wait for batch to flush
        await page.waitForTimeout(100);

        // Verify single batch request
        expect(requests.length).toBe(1);

        // Verify all counters updated
        const counter1 = await page.$eval('[data-live-component="counter:1"]', el => el.textContent);
        const counter2 = await page.$eval('[data-live-component="counter:2"]', el => el.textContent);
        const counter3 = await page.$eval('[data-live-component="counter:3"]', el => el.textContent);

        expect(counter1).toContain('1');
        expect(counter2).toContain('1');
        expect(counter3).toContain('1');
    });

    test('handles partial batch failures gracefully', async () => {
        const result = await page.evaluate(async () => {
            return await LiveComponent.executeBatch([
                { componentId: 'valid:1', method: 'validAction' },
                { componentId: 'invalid:999', method: 'nonexistent' },
                { componentId: 'valid:2', method: 'validAction' }
            ], { autoApply: false });
        });

        expect(result.total_operations).toBe(3);
        expect(result.success_count).toBe(2);
        expect(result.failure_count).toBe(1);

        // Verify successful operations applied
        const valid1 = await page.$('[data-live-component="valid:1"]');
        const valid2 = await page.$('[data-live-component="valid:2"]');
        expect(valid1).not.toBeNull();
        expect(valid2).not.toBeNull();
    });
});

Running E2E Tests

Development

# Start dev server
npm run dev

# Run E2E tests in another terminal
npm run test:e2e

# Run with UI
npm run test:e2e:ui

# Debug mode
npm run test:e2e:debug

CI/CD

# Headless mode
npm run test:e2e:ci

Test Components

E2E tests require test components deployed at known URLs:

  • /live-component/demo - Basic fragment update demo
  • /live-component/batch-demo - Batch update demo
  • /live-component/performance - Performance benchmark page

Performance Validation

E2E tests should validate the performance claims:

  • Fragment Updates: 60-90% bandwidth reduction, 70-95% DOM operation reduction
  • Request Batching: 60-80% request reduction, ~40% total bytes reduction

Visual Regression Testing

Consider adding visual regression tests using:

  • Playwright's screenshot comparison
  • Percy.io
  • Chromatic

Accessibility Testing

E2E tests should include a11y checks:

  • Focus management during updates
  • ARIA live regions for dynamic content
  • Keyboard navigation preservation

Browser Coverage

Test across:

  • Chrome/Chromium
  • Firefox
  • Safari
  • Edge

Future Enhancements

  • Implement full Playwright test suite
  • Add visual regression tests
  • Add accessibility tests
  • Add mobile device tests
  • Add network throttling tests
  • Add WebSocket/SSE update tests
  • Add offline mode tests (PWA)