test(ocr): replace 8 setTimeout sleeps in OcrProgress with vi.waitFor
waitForSource() helper polls for the EventSource constructor effect to register the mock; assertion blocks use vi.waitFor on the progress bar / heading / button changes after each SSE event dispatch. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -41,6 +41,11 @@ afterEach(() => {
|
|||||||
lastSource = null;
|
lastSource = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function waitForSource(): Promise<MockEventSource> {
|
||||||
|
await vi.waitFor(() => expect(lastSource).not.toBeNull());
|
||||||
|
return lastSource as MockEventSource;
|
||||||
|
}
|
||||||
|
|
||||||
describe('OcrProgress', () => {
|
describe('OcrProgress', () => {
|
||||||
it('renders the running progress block by default', async () => {
|
it('renders the running progress block by default', async () => {
|
||||||
render(OcrProgress, { props: { jobId: 'job-1', onDone: () => {} } });
|
render(OcrProgress, { props: { jobId: 'job-1', onDone: () => {} } });
|
||||||
@@ -57,33 +62,31 @@ describe('OcrProgress', () => {
|
|||||||
it('updates the progress bar when document events arrive', async () => {
|
it('updates the progress bar when document events arrive', async () => {
|
||||||
render(OcrProgress, { props: { jobId: 'job-1', onDone: () => {} } });
|
render(OcrProgress, { props: { jobId: 'job-1', onDone: () => {} } });
|
||||||
|
|
||||||
// Wait a tick for $effect to run and EventSource to be created.
|
const src = await waitForSource();
|
||||||
await new Promise((r) => setTimeout(r, 50));
|
src.dispatch('document', { processed: 5, total: 10 });
|
||||||
lastSource?.dispatch('document', { processed: 5, total: 10 });
|
|
||||||
await new Promise((r) => setTimeout(r, 50));
|
|
||||||
|
|
||||||
const bar = (await page.getByRole('progressbar').element()) as HTMLElement;
|
await vi.waitFor(async () => {
|
||||||
expect(bar.getAttribute('aria-valuenow')).toBe('50');
|
const bar = (await page.getByRole('progressbar').element()) as HTMLElement;
|
||||||
|
expect(bar.getAttribute('aria-valuenow')).toBe('50');
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
it('switches to the done state and calls onDone when the done event arrives', async () => {
|
it('switches to the done state and calls onDone when the done event arrives', async () => {
|
||||||
const onDone = vi.fn();
|
const onDone = vi.fn();
|
||||||
render(OcrProgress, { props: { jobId: 'job-1', onDone } });
|
render(OcrProgress, { props: { jobId: 'job-1', onDone } });
|
||||||
|
|
||||||
await new Promise((r) => setTimeout(r, 50));
|
const src = await waitForSource();
|
||||||
lastSource?.dispatch('done', {});
|
src.dispatch('done', {});
|
||||||
await new Promise((r) => setTimeout(r, 50));
|
|
||||||
|
|
||||||
expect(onDone).toHaveBeenCalledOnce();
|
await vi.waitFor(() => expect(onDone).toHaveBeenCalledOnce());
|
||||||
await expect.element(page.getByRole('heading', { name: /ocr läuft/i })).not.toBeInTheDocument();
|
await expect.element(page.getByRole('heading', { name: /ocr läuft/i })).not.toBeInTheDocument();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('switches to the error state when the error event arrives', async () => {
|
it('switches to the error state when the error event arrives', async () => {
|
||||||
render(OcrProgress, { props: { jobId: 'job-1', onDone: () => {} } });
|
render(OcrProgress, { props: { jobId: 'job-1', onDone: () => {} } });
|
||||||
|
|
||||||
await new Promise((r) => setTimeout(r, 50));
|
const src = await waitForSource();
|
||||||
lastSource?.dispatch('error', {});
|
src.dispatch('error', {});
|
||||||
await new Promise((r) => setTimeout(r, 50));
|
|
||||||
|
|
||||||
await expect.element(page.getByRole('heading', { name: /ocr fehlgeschlagen/i })).toBeVisible();
|
await expect.element(page.getByRole('heading', { name: /ocr fehlgeschlagen/i })).toBeVisible();
|
||||||
});
|
});
|
||||||
@@ -91,9 +94,8 @@ describe('OcrProgress', () => {
|
|||||||
it('renders the retry button in the error state', async () => {
|
it('renders the retry button in the error state', async () => {
|
||||||
render(OcrProgress, { props: { jobId: 'job-1', onDone: () => {} } });
|
render(OcrProgress, { props: { jobId: 'job-1', onDone: () => {} } });
|
||||||
|
|
||||||
await new Promise((r) => setTimeout(r, 50));
|
const src = await waitForSource();
|
||||||
lastSource?.dispatch('error', {});
|
src.dispatch('error', {});
|
||||||
await new Promise((r) => setTimeout(r, 50));
|
|
||||||
|
|
||||||
await expect.element(page.getByRole('button', { name: /erneut versuchen/i })).toBeVisible();
|
await expect.element(page.getByRole('button', { name: /erneut versuchen/i })).toBeVisible();
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user