Files
openhuman/app/test/e2e/specs/local-model-runtime.spec.ts
T
2026-05-19 22:46:56 -07:00

106 lines
3.4 KiB
TypeScript

// @ts-nocheck
import { waitForApp, waitForAppReady } from '../helpers/app-helpers';
import { triggerAuthDeepLink } from '../helpers/deep-link-helpers';
import {
clickText,
dumpAccessibilityTree,
textExists,
waitForText,
waitForWebView,
waitForWindowVisible,
} from '../helpers/element-helpers';
import { walkOnboarding } from '../helpers/shared-flows';
import { clearRequestLog, getRequestLog, startMockServer, stopMockServer } from '../mock-server';
async function waitForRequest(method, urlFragment, timeout = 15_000) {
const deadline = Date.now() + timeout;
while (Date.now() < deadline) {
const log = getRequestLog();
const match = log.find(r => r.method === method && r.url.includes(urlFragment));
if (match) return match;
await browser.pause(500);
}
return undefined;
}
async function waitForHome(timeout = 20_000) {
// Home.tsx renders t('home.askAssistant') = 'Ask your assistant anything...' as stable CTA.
const deadline = Date.now() + timeout;
while (Date.now() < deadline) {
if (await textExists('Ask your assistant anything')) return true;
if (await textExists('Your device is connected')) return true;
await browser.pause(700);
}
return false;
}
async function waitForAnyText(candidates, timeout = 20_000) {
const deadline = Date.now() + timeout;
while (Date.now() < deadline) {
for (const t of candidates) {
if (await textExists(t)) return t;
}
await browser.pause(600);
}
return null;
}
// Local model runtime now talks to an external Ollama endpoint through core.
// CI does not provision a live Ollama server, so keep this spec skipped until
// a deterministic mockable local-runtime harness exists for WDIO.
describe.skip('Local model runtime flow', () => {
before(async function beforeSuite() {
this.timeout(90_000);
await startMockServer();
await waitForApp();
clearRequestLog();
});
after(async () => {
await stopMockServer();
});
it('shows direct-runtime guidance instead of app-managed bootstrap controls', async function () {
this.timeout(90_000);
await triggerAuthDeepLink('e2e-local-model-token');
await waitForWindowVisible(25_000);
await waitForWebView(15_000);
await waitForAppReady(15_000);
const consume = await waitForRequest('POST', '/telegram/login-tokens/');
expect(consume).toBeDefined();
await walkOnboarding('[LocalModel]');
const onHome = await waitForHome(20_000);
if (!onHome) {
const tree = await dumpAccessibilityTree();
console.log('[LocalModelE2E] Home not reached. Tree:\n', tree.slice(0, 4000));
}
expect(onHome).toBe(true);
await waitForText('Local model runtime', 15_000);
await clickText('Manage', 10_000);
await waitForText('Runtime Status', 15_000);
const incompatibleError =
'Local model runtime is unavailable in this core build. Restart app after updating to the latest build.';
expect(await textExists(incompatibleError)).toBe(false);
const guidance = await waitForAnyText(
[
'Ollama runtime unavailable',
'Manage the Ollama process and model pulls outside OpenHuman.',
'Ollama docs',
],
25_000
);
if (!guidance) {
const tree = await dumpAccessibilityTree();
console.log('[LocalModelE2E] No direct-runtime guidance seen. Tree:\n', tree.slice(0, 5000));
}
expect(guidance).not.toBeNull();
});
});