Files
blackcanyontickets/reactrebuild0825/tests/qr-system.spec.ts
dzinesco aa81eb5adb feat: add advanced analytics and territory management system
- Add comprehensive analytics components with export functionality
- Implement territory management with manager performance tracking
- Add seatmap components for venue layout management
- Create customer management features with modal interface
- Add advanced hooks for dashboard flags and territory data
- Implement seat selection and venue management utilities
- Add type definitions for ticketing and seatmap systems

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-26 09:25:10 -06:00

219 lines
7.5 KiB
TypeScript

/**
* QR Code System End-to-End Tests
* Tests QR validation, manual entry, and scanner integration
*/
import { test, expect } from '@playwright/test';
test.describe('QR Code System', () => {
test.beforeEach(async ({ page }) => {
// Navigate to scanner page with event ID
await page.goto('/scanner?eventId=test-event-123');
// Wait for scanner to initialize
await page.waitForSelector('[data-testid="scanner-interface"]', { timeout: 10000 });
});
test('should display manual entry button in scanner interface', async ({ page }) => {
// Check for manual entry button (hash icon)
const manualEntryButton = page.locator('button[title="Manual Entry"]');
await expect(manualEntryButton).toBeVisible();
// Verify button has hash icon
await expect(manualEntryButton.locator('svg')).toBeVisible();
});
test('should open manual entry modal when hash button clicked', async ({ page }) => {
// Click manual entry button
await page.click('button[title="Manual Entry"]');
// Verify modal opens
await expect(page.locator('h2:text("Manual Entry")')).toBeVisible();
// Verify keypad is present
await expect(page.locator('button:text("1")')).toBeVisible();
await expect(page.locator('button:text("2")')).toBeVisible();
await expect(page.locator('button:text("3")')).toBeVisible();
});
test('manual entry modal should have proper keyboard navigation', async ({ page }) => {
await page.click('button[title="Manual Entry"]');
// Test numeric input
await page.keyboard.press('1');
await page.keyboard.press('2');
await page.keyboard.press('3');
await page.keyboard.press('4');
await page.keyboard.press('A');
await page.keyboard.press('B');
await page.keyboard.press('C');
await page.keyboard.press('D');
// Verify code display shows entered characters
const codeDisplay = page.locator('div').filter({ hasText: /1234-ABCD/ }).first();
await expect(codeDisplay).toBeVisible();
});
test('should validate backup codes properly', async ({ page }) => {
await page.click('button[title="Manual Entry"]');
// Enter invalid code (too short)
await page.keyboard.press('1');
await page.keyboard.press('2');
await page.keyboard.press('3');
// Submit button should be disabled
const submitButton = page.locator('button:text("Submit")');
await expect(submitButton).toBeDisabled();
// Complete valid code
await page.keyboard.press('4');
await page.keyboard.press('A');
await page.keyboard.press('B');
await page.keyboard.press('C');
await page.keyboard.press('D');
// Submit button should be enabled
await expect(submitButton).toBeEnabled();
});
test('should handle manual entry submission', async ({ page }) => {
await page.click('button[title="Manual Entry"]');
// Enter a complete backup code
await page.keyboard.press('1');
await page.keyboard.press('2');
await page.keyboard.press('3');
await page.keyboard.press('4');
await page.keyboard.press('A');
await page.keyboard.press('B');
await page.keyboard.press('C');
await page.keyboard.press('D');
// Submit the code
await page.click('button:text("Submit")');
// Modal should close and scan result should appear
await expect(page.locator('h2:text("Manual Entry")')).toBeHidden();
// Should show scan result (either success or error)
await expect(page.locator('[class*="ring-2"]')).toBeVisible({ timeout: 5000 });
});
test('should close modal on escape key', async ({ page }) => {
await page.click('button[title="Manual Entry"]');
// Verify modal is open
await expect(page.locator('h2:text("Manual Entry")')).toBeVisible();
// Press escape
await page.keyboard.press('Escape');
// Modal should close
await expect(page.locator('h2:text("Manual Entry")')).toBeHidden();
});
test('should show letter keys when toggle is clicked', async ({ page }) => {
await page.click('button[title="Manual Entry"]');
// Initially letters should be hidden
await expect(page.locator('button:text("A")')).toBeHidden();
// Click show letters toggle
await page.click('button:text("Show Letters A-F")');
// Letters should now be visible
await expect(page.locator('button:text("A")')).toBeVisible();
await expect(page.locator('button:text("B")')).toBeVisible();
await expect(page.locator('button:text("F")')).toBeVisible();
// Toggle text should change
await expect(page.locator('button:text("Hide Letters A-F")')).toBeVisible();
});
test('should clear code when clear button clicked', async ({ page }) => {
await page.click('button[title="Manual Entry"]');
// Enter some characters
await page.keyboard.press('1');
await page.keyboard.press('2');
await page.keyboard.press('3');
// Verify characters are displayed
await expect(page.locator('div').filter({ hasText: /123/ }).first()).toBeVisible();
// Click clear button
await page.click('button:text("Clear")');
// Code should be cleared (showing underscores)
await expect(page.locator('div').filter({ hasText: /____-____/ }).first()).toBeVisible();
});
test('should delete characters when delete button clicked', async ({ page }) => {
await page.click('button[title="Manual Entry"]');
// Enter some characters
await page.keyboard.press('1');
await page.keyboard.press('2');
await page.keyboard.press('3');
await page.keyboard.press('4');
// Verify 4 characters
await expect(page.locator('div').filter({ hasText: /1234/ }).first()).toBeVisible();
// Click delete button
await page.locator('button').filter({ has: page.locator('svg') }).first().click();
// Should show 3 characters
await expect(page.locator('div').filter({ hasText: /123_/ }).first()).toBeVisible();
});
test('should have instructions updated for manual entry', async ({ page }) => {
// Check that scanner instructions mention manual entry
await expect(page.locator('text=Use # button for manual entry when QR is unreadable')).toBeVisible();
});
test('should work with touch events for mobile devices', async ({ page, isMobile }) => {
if (!isMobile) {
test.skip('Mobile-only test');
}
await page.click('button[title="Manual Entry"]');
// Test touch interactions on keypad buttons
await page.tap('button:text("1")');
await page.tap('button:text("2")');
await page.tap('button:text("3")');
await page.tap('button:text("4")');
// Verify touch input works
await expect(page.locator('div').filter({ hasText: /1234/ }).first()).toBeVisible();
});
test('should handle offline mode with manual entry', async ({ page }) => {
// Simulate offline mode
await page.route('**/*', (route) => {
if (route.request().url().includes('api')) {
route.abort('failed');
} else {
route.continue();
}
});
await page.click('button[title="Manual Entry"]');
// Enter valid backup code
const backupCode = '1234ABCD';
for (const char of backupCode) {
await page.keyboard.press(char);
}
// Submit should work even offline
await page.click('button:text("Submit")');
// Should show offline acceptance or queued status
await expect(
page.locator('text=Accepted (offline mode), text=Queued for verification').first()
).toBeVisible({ timeout: 5000 });
});
});