test(e2e): fix macOS providers shard — canonical home markers + macOS-adequate timeouts (#4618) (#4666)

This commit is contained in:
CodeGhost21
2026-07-07 13:58:52 -07:00
committed by GitHub
parent fac8b5f1ae
commit e5ee20be6c
2 changed files with 31 additions and 23 deletions
+16 -20
View File
@@ -36,7 +36,7 @@ import {
waitForText,
} from '../helpers/element-helpers';
import { resetApp } from '../helpers/reset-app';
import { navigateToSettings, navigateViaHash } from '../helpers/shared-flows';
import { navigateToSettings, navigateViaHash, waitForHomePage } from '../helpers/shared-flows';
import { startMockServer, stopMockServer } from '../mock-server';
const USER_ID = 'e2e-cron-jobs';
@@ -51,18 +51,6 @@ function stepLog(message: string, context?: unknown): void {
console.log(`[CronJobsE2E][${stamp}] ${message}`, JSON.stringify(context, null, 2));
}
/** Wait for an element matching one of several texts to be visible. */
async function waitForAnyText(candidates: string[], timeoutMs = 10_000): Promise<string | null> {
const deadline = Date.now() + timeoutMs;
while (Date.now() < deadline) {
for (const text of candidates) {
if (await textExists(text)) return text;
}
await browser.pause(500);
}
return null;
}
async function waitForCronPanel(timeoutMs = 5_000): Promise<void> {
try {
await waitForTestId('cron-jobs-panel', timeoutMs);
@@ -118,12 +106,14 @@ describe('Cron jobs settings panel (real UI flow)', () => {
});
it('completing onboarding lands the user on the home screen', async () => {
// Home.tsx renders t('home.askAssistant') = 'Ask your assistant anything...' as the stable
// CTA button. Old strings ('Good morning', 'Message OpenHuman', etc.) are no longer rendered.
const home = await waitForAnyText(
['Ask your assistant anything', 'Your device is connected'],
15_000
);
// `/home` redirects to `/chat` (AppRoutes.tsx), so the landed surface can render
// either the CTA `home.askAssistant` ('Ask your assistant anything...') OR the
// `home.statusOk` hero ('Your assistant is ready when you are. Type something below
// to get started.'). Use the canonical waitForHomePage() helper — the same one
// resetApp() and every other spec use — which accepts the full marker set, instead
// of a stale subset that only matched the CTA and flaked on the slower macOS runner
// whenever the statusOk hero rendered first.
const home = await waitForHomePage(20_000);
expect(home).toBeTruthy();
});
@@ -157,6 +147,10 @@ describe('Cron jobs settings panel (real UI flow)', () => {
await waitForCronRow(MORNING_BRIEFING, 10_000);
}
expect(await textExists(MORNING_BRIEFING)).toBe(true);
// The 'Enabled' status badge (CoreJobList renders t('common.enabled')) can paint a
// beat after the row name. Poll for it instead of point-checking right away — the
// bare textExists() check raced the render on the slower macOS runner.
await waitForText('Enabled', 10_000);
expect(await textExists('Enabled')).toBe(true);
});
@@ -186,8 +180,10 @@ describe('Cron jobs settings panel (real UI flow)', () => {
await clickNativeButton('Remove', 8_000);
// UI assertion first — the row should disappear and the empty state appear.
// The removal RPC + optimistic re-render can take longer on the slower macOS
// runner, so poll for up to 20s rather than 10s before declaring the row stuck.
const gone = await browser.waitUntil(async () => !(await textExists(MORNING_BRIEFING)), {
timeout: 10_000,
timeout: 20_000,
interval: 500,
timeoutMsg: 'morning_briefing row never disappeared',
});
@@ -341,7 +341,13 @@ describe('Telegram channel — connect / receive / send / disconnect', () => {
// ──────────────────────────────────────────────────────────────────────────
it('C.5 inbound text message round-trip — inject update; observe or document reply path', async function () {
this.timeout(60_000);
// Internal budget is up to 30s (getUpdates poll) + 25s (reply) + connect/LLM
// overhead — that sums past a 60s ceiling on the slower macOS runner, so the
// working round-trip blew the Mocha `it` timeout instead of asserting. 90s
// (matching C.7) gives the observed flow headroom without masking a real hang:
// the getUpdates soft-pass at line ~386 still short-circuits if the listener
// never polls.
this.timeout(90_000);
console.log(`${LOG_PREFIX} C.5: setting up inbound message round-trip`);
// First ensure the bot is connected (writes credentials + TOML config).
@@ -432,7 +438,10 @@ describe('Telegram channel — connect / receive / send / disconnect', () => {
// ──────────────────────────────────────────────────────────────────────────
it('C.6 unauthorized user — connect with allowlist; excluded sender gets approval prompt', async function () {
this.timeout(60_000);
// 30s getUpdates poll + 20s reply wait + connect/LLM overhead exceeds 60s on the
// slower macOS runner; 90s fits the working flow. The getUpdates soft-pass still
// guards against a genuinely dead listener.
this.timeout(90_000);
console.log(`${LOG_PREFIX} C.6: connecting with allowlist excluding Bob`);
// Connect with Alice in the allowlist — Bob is excluded.
@@ -653,7 +662,10 @@ describe('Telegram channel — connect / receive / send / disconnect', () => {
// ──────────────────────────────────────────────────────────────────────────
it('C.10 remote /status command — bot replies with Thread: and Provider: markers', async function () {
this.timeout(60_000);
// 30s listener poll + 20s reply wait + connect/LLM overhead exceeds 60s on the
// slower macOS runner; 90s fits the working flow. The getUpdates soft-pass still
// guards against a genuinely dead listener.
this.timeout(90_000);
console.log(`${LOG_PREFIX} C.10: setting up /status command scenario`);
await connectTelegramBot({ botToken: BOT_TOKEN, allowedUsers: [ALICE_USERNAME] });