/**
* E2E でアプリの起動が完了するまで待機する。
* 1) フロントのメイン UI(#query)が表示されるまで待つ
* 2) MCP (3001) の /edition が応答するまでポーリング
*
* 各 spec の before() で呼ぶこと。
* @param {import('@wdio/globals').browser} browser - WDIO browser
* @param {{ uiTimeout?: number, mcpTimeout?: number, mcpInterval?: number }} [opts]
*/
export async function waitForAppReady(browser, opts = {}) {
const uiTimeout = opts.uiTimeout ?? 25000;
const mcpMaxAttempts = Math.floor((opts.mcpTimeout ?? 90000) / (opts.mcpInterval ?? 500));
const mcpIntervalMs = opts.mcpInterval ?? 500;
const query = await browser.$('#query');
await query.waitForDisplayed({ timeout: uiTimeout });
const fetchTimeoutMs = 8000;
for (let i = 0; i < mcpMaxAttempts; i++) {
const ok = await browser.executeAsync(function (timeoutMs, done) {
let settled = false;
const finish = (result) => {
if (settled) return;
settled = true;
done(result);
};
const t = setTimeout(() => finish(false), timeoutMs);
fetch('http://127.0.0.1:3001/edition')
.then((r) => finish(r.ok))
.catch(() => finish(false))
.finally(() => clearTimeout(t));
}, fetchTimeoutMs);
if (ok) return;
await browser.pause(mcpIntervalMs);
}
throw new Error('MCP (3001) did not become ready in time');
}