Expand accessibility tests for ConfirmDialog to assert dialog semantics, ARIA attributes, and visible destructive actions using test IDs. Refactor expectMediaState helper to check both UI control state and underlying media signals for more robust playback state detection.
92 lines
3.5 KiB
TypeScript
92 lines
3.5 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import {
|
|
setupTest,
|
|
uploadFiles,
|
|
ensureDocumentsListed,
|
|
uploadAndDisplay,
|
|
expectProcessingTransition,
|
|
pauseTTSAndVerify,
|
|
} from './helpers';
|
|
|
|
test.describe('Accessibility smoke', () => {
|
|
test.beforeEach(async ({ page }, testInfo) => {
|
|
await setupTest(page, testInfo);
|
|
});
|
|
|
|
test('dropzone input and hint text are accessible', async ({ page }) => {
|
|
// Input is present and visible
|
|
await expect(page.locator('input[type="file"]').first()).toBeVisible({ timeout: 10000 });
|
|
|
|
// Hint text present (supports compact or default variants)
|
|
await expect(
|
|
page.getByText(/Drop your file\(s\) here|Drop files or click|Drop your file\(s\) here, or click to select/i)
|
|
).toBeVisible();
|
|
});
|
|
|
|
test('document links have roles and accessible names', async ({ page }) => {
|
|
await uploadFiles(page, 'sample.pdf', 'sample.epub', 'sample.txt');
|
|
await ensureDocumentsListed(page, ['sample.pdf', 'sample.epub', 'sample.txt']);
|
|
|
|
await expect(page.getByRole('link', { name: /^sample\.pdf$/i })).toBeVisible();
|
|
await expect(page.getByRole('link', { name: /^sample\.epub$/i })).toBeVisible();
|
|
await expect(page.getByRole('link', { name: /^sample\.txt$/i })).toBeVisible();
|
|
});
|
|
|
|
test('ConfirmDialog exposes role=dialog with title and actions', async ({ page }) => {
|
|
await uploadFiles(page, 'sample.pdf');
|
|
await ensureDocumentsListed(page, ['sample.pdf']);
|
|
|
|
// Open the confirm dialog by clicking the row delete button
|
|
await page.getByRole('button', { name: /^Delete sample\.pdf$/i }).first().click();
|
|
|
|
// Title and dialog semantics are present
|
|
const heading = page.getByRole('heading', { name: 'Delete Document' });
|
|
await expect(heading).toBeVisible({ timeout: 10000 });
|
|
const dialog = page.getByRole('dialog', { name: 'Delete Document' }).first();
|
|
await expect(dialog).toHaveAttribute('aria-modal', 'true');
|
|
|
|
// The visible panel content is rendered and includes destructive action
|
|
const panel = page.getByTestId('confirm-dialog-panel').first();
|
|
await expect(panel).toBeVisible();
|
|
|
|
// Has a destructive action (Delete)
|
|
await expect(panel.getByRole('button', { name: /^Delete$/ })).toBeVisible();
|
|
|
|
// Close with Escape to avoid deleting test data
|
|
await page.keyboard.press('Escape');
|
|
});
|
|
|
|
test('TTS controls expose aria labels and are keyboard focusable', async ({ page }) => {
|
|
test.setTimeout(120_000);
|
|
await uploadAndDisplay(page, 'sample.pdf');
|
|
|
|
// TTS bar present
|
|
const ttsbar = page.locator('[data-app-ttsbar]');
|
|
await expect(ttsbar).toBeVisible();
|
|
|
|
// Verify control labels
|
|
const backBtn = page.getByRole('button', { name: 'Skip backward' });
|
|
const playBtn = page.getByRole('button', { name: 'Play' });
|
|
const fwdBtn = page.getByRole('button', { name: 'Skip forward' });
|
|
|
|
await expect(backBtn).toBeVisible();
|
|
await expect(playBtn).toBeVisible();
|
|
await expect(fwdBtn).toBeVisible();
|
|
|
|
// Keyboard focus checks
|
|
await page.focus('button[aria-label="Skip backward"]');
|
|
await expect(backBtn).toBeFocused();
|
|
|
|
await page.focus('button[aria-label="Play"]');
|
|
await expect(playBtn).toBeFocused();
|
|
|
|
await page.focus('button[aria-label="Skip forward"]');
|
|
await expect(fwdBtn).toBeFocused();
|
|
|
|
// Toggle play and verify aria-label swap to Pause, then back to Play
|
|
await playBtn.click();
|
|
await expectProcessingTransition(page);
|
|
await expect(page.getByRole('button', { name: 'Pause' })).toBeVisible();
|
|
await pauseTTSAndVerify(page);
|
|
});
|
|
});
|