Update tests

This commit is contained in:
Richard Roberson 2025-03-02 20:19:52 -07:00
parent 521aafe8e0
commit 4aaa74414f
4 changed files with 43 additions and 38 deletions

View file

@ -22,7 +22,7 @@ jobs:
NEXT_PUBLIC_NODE_ENV: test NEXT_PUBLIC_NODE_ENV: test
API_BASE: https://tts.richardr.dev/v1 API_BASE: https://tts.richardr.dev/v1
API_KEY: not-needed API_KEY: not-needed
run: npx playwright test --reporter=list,github,html run: npx playwright test --reporter=github,html
- uses: actions/upload-artifact@v4 - uses: actions/upload-artifact@v4
if: ${{ !cancelled() }} if: ${{ !cancelled() }}
with: with:

View file

@ -20,7 +20,7 @@ export default defineConfig({
/* Fail the build on CI if you accidentally left test.only in the source code. */ /* Fail the build on CI if you accidentally left test.only in the source code. */
forbidOnly: !!process.env.CI, forbidOnly: !!process.env.CI,
/* Retry on CI only */ /* Retry on CI only */
retries: process.env.CI ? 1 : 0, retries: process.env.CI ? 2 : 0,
/* Opt out of parallel tests on CI. */ /* Opt out of parallel tests on CI. */
workers: undefined, workers: undefined,
/* Reporter to use. See https://playwright.dev/docs/test-reporters */ /* Reporter to use. See https://playwright.dev/docs/test-reporters */

View file

@ -50,7 +50,7 @@ export async function POST(req: NextRequest) {
return new NextResponse(null, { status: 499 }); // Use 499 status for client closed request return new NextResponse(null, { status: 499 }); // Use 499 status for client closed request
} }
console.error('Error generating TTS:', error); console.warn('Error generating TTS:', error);
return NextResponse.json( return NextResponse.json(
{ error: 'Failed to generate audio' }, { error: 'Failed to generate audio' },
{ status: 500 } { status: 500 }

View file

@ -13,8 +13,8 @@ async function uploadAndDisplay(page: Page, fileName: string) {
await uploadFile(page, fileName); await uploadFile(page, fileName);
// Wait for link with document-link class // Wait for link with document-link class
await page.waitForSelector('.document-link', { timeout: 20000 }); const size = fileName.endsWith('.pdf') ? '0.02 MB' : '0.33 MB';
await page.getByText(fileName).click(); await page.getByRole('link', { name: `${fileName} ${size}` }).click();
// Wait for the document to load // Wait for the document to load
if (fileName.endsWith('.pdf')) { if (fileName.endsWith('.pdf')) {
@ -27,25 +27,23 @@ async function uploadAndDisplay(page: Page, fileName: string) {
async function waitAndClickPlay(page: Page) { async function waitAndClickPlay(page: Page) {
// Wait for play button selector without disabled attribute // Wait for play button selector without disabled attribute
await page.waitForSelector('button[aria-label="Play"]:not([disabled])', { timeout: 20000 }); await expect(page.getByRole('button', { name: 'Play' })).toBeVisible();
// Play the TTS by aria-label play button // Play the TTS by clicking the button
await page.locator('button[aria-label="Play"]').click(); await page.getByRole('button', { name: 'Play' }).click();
// Wait for buttons to be disabled // Expect for buttons to be disabled
await Promise.all([ await expect(page.locator('button[aria-label="Skip forward"][disabled]')).toBeVisible();
page.waitForSelector('button[aria-label="Skip forward"][disabled]'), await expect(page.locator('button[aria-label="Skip backward"][disabled]')).toBeVisible();
page.waitForSelector('button[aria-label="Skip backward"][disabled]'),
]);
// Wait for the TTS to stop processing // Wait for the TTS to stop processing
await Promise.all([ await Promise.all([
page.waitForSelector('button[aria-label="Skip forward"]:not([disabled])', { timeout: 30000 }), page.waitForSelector('button[aria-label="Skip forward"]:not([disabled])', { timeout: 45000 }),
page.waitForSelector('button[aria-label="Skip backward"]:not([disabled])', { timeout: 30000 }), page.waitForSelector('button[aria-label="Skip backward"]:not([disabled])', { timeout: 45000 }),
]); ]);
await page.waitForFunction(() => { await page.waitForFunction(() => {
return navigator.mediaSession?.playbackState === 'playing'; return navigator.mediaSession?.playbackState === 'playing';
}, { timeout: 30000 }) });
} }
async function playTTSAndWaitForASecond(page: Page, fileName: string) { async function playTTSAndWaitForASecond(page: Page, fileName: string) {
@ -61,12 +59,14 @@ test.describe('Document flow', () => {
test.beforeEach(async ({ page }) => { test.beforeEach(async ({ page }) => {
// Navigate to the home page before each test // Navigate to the home page before each test
await page.goto('/'); await page.goto('/');
await page.waitForLoadState('networkidle');
// Click the "done" button to dismiss the welcome message // Click the "done" button to dismiss the welcome message
await page.getByText('Done').click(); await page.getByText('Done').click();
}); });
test.describe('PDF check', () => { // Basic upload tests can run in parallel
test.describe('Basic document tests', () => {
test('upload a PDF document', async ({ page }) => { test('upload a PDF document', async ({ page }) => {
// Upload the file // Upload the file
await uploadFile(page, 'sample.pdf'); await uploadFile(page, 'sample.pdf');
@ -75,6 +75,13 @@ test.describe('Document flow', () => {
await expect(page.getByText('sample.pdf')).toBeVisible({ timeout: 10000 }); await expect(page.getByText('sample.pdf')).toBeVisible({ timeout: 10000 });
}); });
test('upload a EPUB document', async ({ page }) => {
// Upload the file
await uploadFile(page, 'sample.epub');
// Verify upload success
await expect(page.getByText('sample.epub')).toBeVisible({ timeout: 10000 });
});
test('display a PDF document', async ({ page }) => { test('display a PDF document', async ({ page }) => {
// Upload and display the PDF document // Upload and display the PDF document
await uploadAndDisplay(page, 'sample.pdf'); await uploadAndDisplay(page, 'sample.pdf');
@ -82,24 +89,7 @@ test.describe('Document flow', () => {
// Verify PDF viewer is displayed // Verify PDF viewer is displayed
await expect(page.locator('.react-pdf__Document')).toBeVisible(); await expect(page.locator('.react-pdf__Document')).toBeVisible();
await expect(page.locator('.react-pdf__Page')).toBeVisible(); await expect(page.locator('.react-pdf__Page')).toBeVisible();
}); await expect(page.getByText('Sample PDF')).toBeVisible();
test('play and pause TTS for a PDF document (naive)', async ({ page }) => {
// Play TTS for the PDF document
await playTTSAndWaitForASecond(page, 'sample.pdf');
// Click pause to stop playback
await page.locator('button[aria-label="Pause"]').click();
// Check for play button to be visible
await expect(page.locator('button[aria-label="Play"]')).toBeVisible({ timeout: 10000 });
});
});
test.describe('EPUB check', () => {
test('upload a EPUB document', async ({ page }) => {
// Upload the file
await uploadFile(page, 'sample.epub');
// Verify upload success
await expect(page.getByText('sample.epub')).toBeVisible({ timeout: 10000 });
}); });
test('display an EPUB document', async ({ page }) => { test('display an EPUB document', async ({ page }) => {
@ -107,15 +97,30 @@ test.describe('Document flow', () => {
await uploadAndDisplay(page, 'sample.epub'); await uploadAndDisplay(page, 'sample.epub');
// Verify EPUB viewer is displayed // Verify EPUB viewer is displayed
await expect(page.locator('.epub-container')).toBeVisible({ timeout: 10000 }); await expect(page.locator('.epub-container')).toBeVisible({ timeout: 10000 });
await expect(page.getByRole('button', { name: '' })).toBeVisible();
await expect(page.getByRole('button', { name: '' })).toBeVisible();
});
});
// TTS tests run with limited concurrency
test.describe('TTS functionality', () => {
test.describe.configure({ mode: 'serial' });
test('play and pause TTS for a PDF document', async ({ page }) => {
// Play TTS for the PDF document
await playTTSAndWaitForASecond(page, 'sample.pdf');
// Click pause to stop playback
await page.getByRole('button', { name: 'Pause' }).click();
// Check for play button to be visible
await expect(page.getByRole('button', { name: 'Play' })).toBeVisible({ timeout: 10000 });
}); });
test('play and pause TTS for an EPUB document (naive)', async ({ page }) => { test('play and pause TTS for an EPUB document', async ({ page }) => {
// Play TTS for the EPUB document // Play TTS for the EPUB document
await playTTSAndWaitForASecond(page, 'sample.epub'); await playTTSAndWaitForASecond(page, 'sample.epub');
// Click pause to stop playback // Click pause to stop playback
await page.locator('button[aria-label="Pause"]').click(); await page.getByRole('button', { name: 'Pause' }).click();
// Check for play button to be visible // Check for play button to be visible
await expect(page.locator('button[aria-label="Play"]')).toBeVisible({ timeout: 10000 }); await expect(page.getByRole('button', { name: 'Play' })).toBeVisible({ timeout: 10000 });
}); });
}); });
}); });