|
|
|
@ -9,6 +9,7 @@
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
import { test, expect } from '@playwright/test';
|
|
|
|
import { test, expect } from '@playwright/test';
|
|
|
|
|
|
|
|
import type { Page } from '@playwright/test';
|
|
|
|
import * as dotenv from 'dotenv';
|
|
|
|
import * as dotenv from 'dotenv';
|
|
|
|
import * as path from 'path';
|
|
|
|
import * as path from 'path';
|
|
|
|
import { loginAsUser } from '../helpers/auth';
|
|
|
|
import { loginAsUser } from '../helpers/auth';
|
|
|
|
@ -20,7 +21,7 @@ const OPENAI_KEY = process.env.OPENAI_TEST_API_KEY;
|
|
|
|
|
|
|
|
|
|
|
|
/** Helper to make an authenticated API call from the browser context. */
|
|
|
|
/** Helper to make an authenticated API call from the browser context. */
|
|
|
|
async function apiCall(
|
|
|
|
async function apiCall(
|
|
|
|
page: any,
|
|
|
|
page: Page,
|
|
|
|
method: string,
|
|
|
|
method: string,
|
|
|
|
url: string,
|
|
|
|
url: string,
|
|
|
|
body?: object,
|
|
|
|
body?: object,
|
|
|
|
@ -47,7 +48,17 @@ async function apiCall(
|
|
|
|
options.body = JSON.stringify(body);
|
|
|
|
options.body = JSON.stringify(body);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
const resp = await fetch(url, options);
|
|
|
|
const resp = await fetch(url, options);
|
|
|
|
const data = await resp.json().catch(() => null);
|
|
|
|
const text = await resp.text();
|
|
|
|
|
|
|
|
let data: unknown = null;
|
|
|
|
|
|
|
|
if (text) {
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
|
|
|
data = JSON.parse(text);
|
|
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
|
|
throw new Error(
|
|
|
|
|
|
|
|
`Expected JSON from ${method} ${url} (status ${resp.status}), got: ${text.slice(0, 200)}`
|
|
|
|
|
|
|
|
);
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
return { status: resp.status, data };
|
|
|
|
return { status: resp.status, data };
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{ method, url, body },
|
|
|
|
{ method, url, body },
|
|
|
|
@ -56,7 +67,7 @@ async function apiCall(
|
|
|
|
|
|
|
|
|
|
|
|
/** Wait for SSE generation to complete, return the synthesis_id. */
|
|
|
|
/** Wait for SSE generation to complete, return the synthesis_id. */
|
|
|
|
async function waitForGenerationComplete(
|
|
|
|
async function waitForGenerationComplete(
|
|
|
|
page: any,
|
|
|
|
page: Page,
|
|
|
|
jobId: string,
|
|
|
|
jobId: string,
|
|
|
|
timeoutMs = 120_000,
|
|
|
|
timeoutMs = 120_000,
|
|
|
|
): Promise<string> {
|
|
|
|
): Promise<string> {
|
|
|
|
@ -73,8 +84,12 @@ async function waitForGenerationComplete(
|
|
|
|
es.addEventListener('complete', (event: MessageEvent) => {
|
|
|
|
es.addEventListener('complete', (event: MessageEvent) => {
|
|
|
|
clearTimeout(timer);
|
|
|
|
clearTimeout(timer);
|
|
|
|
es.close();
|
|
|
|
es.close();
|
|
|
|
const parsed = JSON.parse(event.data);
|
|
|
|
try {
|
|
|
|
resolve(parsed.synthesis_id);
|
|
|
|
const parsed = JSON.parse(event.data);
|
|
|
|
|
|
|
|
resolve(parsed.synthesis_id);
|
|
|
|
|
|
|
|
} catch {
|
|
|
|
|
|
|
|
reject(new Error(`Invalid JSON in complete event: ${event.data}`));
|
|
|
|
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
es.addEventListener('error', (event: MessageEvent) => {
|
|
|
|
es.addEventListener('error', (event: MessageEvent) => {
|
|
|
|
clearTimeout(timer);
|
|
|
|
clearTimeout(timer);
|
|
|
|
|