75 lines
2.5 KiB
TypeScript
75 lines
2.5 KiB
TypeScript
/**
|
|
* E2E Test: Mobile Responsive Flow
|
|
* Priority: HIGH - Mobile user experience
|
|
*
|
|
* Tests mobile responsive behavior:
|
|
* 1. Mobile navigation
|
|
* 2. Touch interactions
|
|
* 3. Responsive layouts
|
|
* 4. Mobile-specific features
|
|
*/
|
|
|
|
import { test, expect, type Page } from '@playwright/test';
|
|
|
|
test.describe('Mobile Responsive Flow', () => {
|
|
test.use({ viewport: { width: 375, height: 667 } }); // iPhone SE size
|
|
|
|
test.beforeEach(async ({ page }: { page: Page }) => {
|
|
await page.goto('http://localhost:3000');
|
|
});
|
|
|
|
test('mobile navigation works', async ({ page }: { page: Page }) => {
|
|
// Step 1: Open mobile menu
|
|
const menuButton = page.locator('button[aria-label*="menu"]').first();
|
|
await menuButton.click();
|
|
|
|
// Step 2: Verify menu is visible
|
|
await expect(page.locator('nav[aria-label*="navigation"]')).toBeVisible({ timeout: 3000 });
|
|
|
|
// Step 3: Navigate to RSVP
|
|
await page.click('text=RSVP');
|
|
await expect(page).toHaveURL(/.*rsvp.*/, { timeout: 3000 });
|
|
|
|
// Step 4: Close menu
|
|
await menuButton.click();
|
|
await expect(page.locator('nav[aria-label*="navigation"]')).not.toBeVisible({ timeout: 3000 });
|
|
});
|
|
|
|
test('touch interactions work', async ({ page }: { page: Page }) => {
|
|
// Authenticate first
|
|
await page.fill('input[placeholder*="invite"]', 'TEST123');
|
|
await page.click('button[type="submit"]');
|
|
await page.waitForURL(/.*dashboard.*/, { timeout: 5000 });
|
|
|
|
// Test swipe on gallery
|
|
await page.click('text=Gallery');
|
|
|
|
// Simulate swipe gesture
|
|
const galleryContainer = page.locator('[data-testid="gallery-container"]').first();
|
|
if (await galleryContainer.isVisible()) {
|
|
await galleryContainer.hover();
|
|
await page.mouse.down();
|
|
await page.mouse.move(100, 0);
|
|
await page.mouse.up();
|
|
}
|
|
});
|
|
|
|
test('responsive layouts adapt to mobile', async ({ page }: { page: Page }) => {
|
|
// Check that layout is mobile-friendly
|
|
const mainContent = page.locator('main').first();
|
|
const boundingBox = await mainContent.boundingBox();
|
|
|
|
expect(boundingBox?.width).toBeLessThanOrEqual(375);
|
|
});
|
|
|
|
test('mobile forms are accessible', async ({ page }: { page: Page }) => {
|
|
await page.goto('http://localhost:3000/rsvp');
|
|
|
|
// Check form inputs are properly sized for mobile
|
|
const input = page.getByPlaceholder(/invite code/i);
|
|
const boundingBox = await input.boundingBox();
|
|
|
|
expect(boundingBox?.width).toBeGreaterThan(200); // Minimum touch target size
|
|
});
|
|
});
|