pp-planer/tests/e2e/ccli-paste-import.spec.ts

114 lines
4.3 KiB
TypeScript

import { test, expect } from '@playwright/test';
import * as fs from 'fs';
function loadFixture(name: string): string {
return fs.readFileSync(`tests/Fixtures/ccli/${name}`, 'utf-8');
}
test.describe('CCLI Paste Import - SongDB', () => {
test('SongDB page shows CCLI import buttons', async ({ page }) => {
await page.goto('/songs');
await page.waitForLoadState('networkidle');
await expect(page.getByTestId('open-ccli-paste-dialog-button-songdb')).toBeVisible();
});
test('SongSelect search button opens new tab with prefilled URL', async ({ page }) => {
await page.goto('/songs');
await page.waitForLoadState('networkidle');
// Fill search input
await page.getByTestId('song-list-search-input').fill('amazing grace');
await page.waitForTimeout(300);
// Click SongSelect search button
const [popup] = await Promise.all([
page.waitForEvent('popup'),
page.getByTestId('songselect-search-button-songdb').click(),
]);
await popup.waitForLoadState('domcontentloaded');
expect(popup.url()).toContain('songselect.ccli.com');
expect(popup.url()).toContain('amazing');
await popup.close();
});
test('opens CCLI paste dialog from SongDB', async ({ page }) => {
await page.goto('/songs');
await page.waitForLoadState('networkidle');
await page.getByTestId('open-ccli-paste-dialog-button-songdb').click();
await expect(page.getByTestId('ccli-paste-textarea')).toBeVisible();
await expect(page.getByTestId('ccli-preview-button')).toBeDisabled();
});
test('preview button disabled when textarea empty', async ({ page }) => {
await page.goto('/songs');
await page.waitForLoadState('networkidle');
await page.getByTestId('open-ccli-paste-dialog-button-songdb').click();
await expect(page.getByTestId('ccli-preview-button')).toBeDisabled();
});
test('paste fixture and preview shows metadata', async ({ page }) => {
await page.goto('/songs');
await page.waitForLoadState('networkidle');
await page.getByTestId('open-ccli-paste-dialog-button-songdb').click();
const content = loadFixture('english-only-multi-verse.txt');
await page.getByTestId('ccli-paste-textarea').fill(content);
await expect(page.getByTestId('ccli-preview-button')).toBeEnabled();
await page.getByTestId('ccli-preview-button').click();
await page.waitForTimeout(3000);
const errorMsg = page.getByTestId('ccli-error-message');
const hasError = await errorMsg.isVisible().catch(() => false);
if (hasError) {
test.skip();
return;
}
await expect(page.locator('text=CCLI-Nr')).toBeVisible({ timeout: 5000 });
});
test('duplicate import shows error with edit link', async ({ page }) => {
const content = loadFixture('english-only-multi-verse.txt');
await page.goto('/songs');
await page.waitForLoadState('networkidle');
const cookies = await page.context().cookies();
const xsrf = cookies.find(c => c.name === 'XSRF-TOKEN')?.value ?? '';
const importRes = await page.request.post('/api/songs/import-from-ccli-paste', {
headers: {
'Content-Type': 'application/json',
'X-XSRF-TOKEN': decodeURIComponent(xsrf),
},
data: { raw_text: content, mode: 'create' },
});
if (importRes.status() !== 201) {
test.skip();
return;
}
// Now try to import again via UI
await page.goto('/songs');
await page.waitForLoadState('networkidle');
await page.getByTestId('open-ccli-paste-dialog-button-songdb').click();
await page.getByTestId('ccli-paste-textarea').fill(content);
await page.getByTestId('ccli-preview-button').click();
await page.waitForTimeout(2000);
// Click import
const importBtn = page.getByTestId('ccli-import-stay-button');
if (await importBtn.isVisible()) {
await importBtn.click();
await page.waitForTimeout(2000);
await expect(page.getByTestId('ccli-error-message')).toBeVisible();
await expect(page.getByTestId('ccli-existing-song-link')).toBeVisible();
}
});
});