149 lines
No EOL
5.6 KiB
TypeScript
149 lines
No EOL
5.6 KiB
TypeScript
import { test, expect } from '@playwright/test';
|
|
import { MockAPIHelper } from '../helpers/auth';
|
|
import { testJobs, testVttContent } from '../fixtures/test-data';
|
|
|
|
test.describe('VTT Editing Workflow', () => {
|
|
let mockAPI: MockAPIHelper;
|
|
|
|
test.beforeEach(async ({ page }) => {
|
|
mockAPI = new MockAPIHelper(page);
|
|
|
|
// Mock authentication
|
|
await mockAPI.mockLoginSuccess('reviewer');
|
|
|
|
// Mock job data
|
|
await mockAPI.mockJobDetail(testJobs.pendingQC.id, testJobs.pendingQC);
|
|
await mockAPI.mockVttContent(testJobs.pendingQC.id, 'en', {
|
|
captions_vtt: testVttContent.captions,
|
|
audio_description_vtt: testVttContent.audioDescription,
|
|
});
|
|
});
|
|
|
|
test('should display VTT editor with content', async ({ page }) => {
|
|
await page.goto(`/jobs/${testJobs.pendingQC.id}/edit`);
|
|
|
|
// Should show VTT editors
|
|
await expect(page.getByText('Captions')).toBeVisible();
|
|
await expect(page.getByText('Audio Description')).toBeVisible();
|
|
|
|
// Should show VTT content
|
|
await expect(page.getByText('Welcome to our video accessibility platform.')).toBeVisible();
|
|
await expect(page.getByText('A person sits at a modern desk with a computer.')).toBeVisible();
|
|
});
|
|
|
|
test('should show timing information', async ({ page }) => {
|
|
await page.goto(`/jobs/${testJobs.pendingQC.id}/edit`);
|
|
|
|
// Should show timing information in proper format
|
|
await expect(page.getByText('0:01.000 → 0:03.500')).toBeVisible();
|
|
await expect(page.getByText('(2500ms)')).toBeVisible();
|
|
});
|
|
|
|
test('should enter edit mode on cue click', async ({ page }) => {
|
|
await page.goto(`/jobs/${testJobs.pendingQC.id}/edit`);
|
|
|
|
// Hover over first cue to show edit button
|
|
const firstCue = page.getByText('Welcome to our video accessibility platform.').locator('..');
|
|
await firstCue.hover();
|
|
|
|
// Click edit button
|
|
await page.getByText('Edit text').first().click();
|
|
|
|
// Should show edit interface
|
|
await expect(page.getByRole('textbox')).toBeVisible();
|
|
await expect(page.getByRole('textbox')).toHaveValue('Welcome to our video accessibility platform.');
|
|
await expect(page.getByText('Save (Ctrl+Enter)')).toBeVisible();
|
|
await expect(page.getByText('Cancel (Esc)')).toBeVisible();
|
|
});
|
|
|
|
test('should save edited cue content', async ({ page }) => {
|
|
// Mock the VTT update API
|
|
await page.route(`**/api/v1/jobs/${testJobs.pendingQC.id}/vtt`, async route => {
|
|
if (route.request().method() === 'PATCH') {
|
|
await route.fulfill({
|
|
status: 200,
|
|
contentType: 'application/json',
|
|
body: JSON.stringify({ ...testJobs.pendingQC, updated_at: new Date().toISOString() }),
|
|
});
|
|
}
|
|
});
|
|
|
|
await page.goto(`/jobs/${testJobs.pendingQC.id}/edit`);
|
|
|
|
// Enter edit mode
|
|
const firstCue = page.getByText('Welcome to our video accessibility platform.').locator('..');
|
|
await firstCue.hover();
|
|
await page.getByText('Edit text').first().click();
|
|
|
|
// Edit the content
|
|
const textarea = page.getByRole('textbox');
|
|
await textarea.clear();
|
|
await textarea.fill('Updated welcome message for accessibility platform.');
|
|
|
|
// Save changes
|
|
await page.getByText('Save (Ctrl+Enter)').click();
|
|
|
|
// Should exit edit mode and show updated content
|
|
await expect(page.getByText('Updated welcome message for accessibility platform.')).toBeVisible();
|
|
await expect(page.getByRole('textbox')).not.toBeVisible();
|
|
});
|
|
|
|
test('should cancel editing without saving', async ({ page }) => {
|
|
await page.goto(`/jobs/${testJobs.pendingQC.id}/edit`);
|
|
|
|
// Enter edit mode
|
|
const firstCue = page.getByText('Welcome to our video accessibility platform.').locator('..');
|
|
await firstCue.hover();
|
|
await page.getByText('Edit text').first().click();
|
|
|
|
// Edit the content
|
|
const textarea = page.getByRole('textbox');
|
|
await textarea.clear();
|
|
await textarea.fill('This should not be saved');
|
|
|
|
// Cancel changes
|
|
await page.getByText('Cancel (Esc)').click();
|
|
|
|
// Should exit edit mode and show original content
|
|
await expect(page.getByText('Welcome to our video accessibility platform.')).toBeVisible();
|
|
await expect(page.getByText('This should not be saved')).not.toBeVisible();
|
|
await expect(page.getByRole('textbox')).not.toBeVisible();
|
|
});
|
|
|
|
test('should support keyboard shortcuts', async ({ page }) => {
|
|
await page.goto(`/jobs/${testJobs.pendingQC.id}/edit`);
|
|
|
|
// Enter edit mode
|
|
const firstCue = page.getByText('Welcome to our video accessibility platform.').locator('..');
|
|
await firstCue.hover();
|
|
await page.getByText('Edit text').first().click();
|
|
|
|
const textarea = page.getByRole('textbox');
|
|
await textarea.clear();
|
|
await textarea.fill('Keyboard shortcut test');
|
|
|
|
// Test Escape to cancel
|
|
await page.keyboard.press('Escape');
|
|
|
|
// Should cancel editing
|
|
await expect(page.getByText('Welcome to our video accessibility platform.')).toBeVisible();
|
|
await expect(page.getByRole('textbox')).not.toBeVisible();
|
|
});
|
|
|
|
test('should show validation errors for invalid VTT', async ({ page }) => {
|
|
// Mock invalid VTT content
|
|
await mockAPI.mockVttContent(testJobs.pendingQC.id, 'en', {
|
|
captions_vtt: `WEBVTT
|
|
|
|
00:00:03.000 --> 00:00:01.000
|
|
Invalid timing order`,
|
|
audio_description_vtt: testVttContent.audioDescription,
|
|
});
|
|
|
|
await page.goto(`/jobs/${testJobs.pendingQC.id}/edit`);
|
|
|
|
// Should show validation errors
|
|
await expect(page.getByText('Validation Errors:')).toBeVisible();
|
|
await expect(page.getByText(/Start time must be before end time/)).toBeVisible();
|
|
});
|
|
}); |