Files
msh-system/tests/e2e/helpers/app-helpers.ts
scottpan 4be53dcd1b feat: 集成 KieAI 服务,移除 models-integration 子项目
- 添加 Gemini 2.5 Flash 对话接口(流式+非流式)
- 添加 NanoBanana 图像生成/编辑接口
- 添加 Sora2 视频生成接口(文生视频、图生视频、去水印)
- 移除 models-integration 子项目(功能已迁移至主后端)
- 新增测试文档和 Playwright E2E 配置
- 更新前端页面和 API 接口
- 更新后端配置和日志处理
2026-03-03 15:33:50 +08:00

78 lines
2.5 KiB
TypeScript

import { Page, FrameLocator, Locator } from '@playwright/test';
/** App base URL (H5 dev server) */
export const BASE_URL = 'http://localhost:8080';
/** Credentials for demo account */
export const TEST_CREDENTIALS = {
phone: '18621813282',
password: 'A123456',
};
/**
* Returns the frame or page to interact with.
* If the page has a #iframe element (pc.html wrapper), use the frame context;
* otherwise use the page directly.
*/
export async function getAppContext(page: Page): Promise<Page | FrameLocator> {
const hasIframe = await page.locator('#iframe').count();
if (hasIframe > 0) {
return page.frameLocator('#iframe');
}
return page;
}
/**
* Navigate to an internal UniApp hash route.
* Works whether we are inside an iframe or directly on root.
*/
export async function goToPage(page: Page, route: string): Promise<void> {
await page.goto(`${BASE_URL}/#/${route}`);
// Brief wait for Vue router & components to hydrate
await page.waitForTimeout(1500);
}
/**
* Perform login flow using phone + password.
* Expects to already be on the login page or navigates there.
*/
export async function login(
page: Page,
phone = TEST_CREDENTIALS.phone,
password = TEST_CREDENTIALS.password,
): Promise<void> {
await goToPage(page, 'pages/users/login/index');
// UniApp H5 renders <input> as native HTML input elements
const phoneInput = page.locator('input[type="number"], input[placeholder*="手机号"]').first();
const passwordInput = page.locator('input[type="password"], input[placeholder*="密码"]').first();
await phoneInput.waitFor({ state: 'visible', timeout: 10_000 });
await phoneInput.fill(phone);
await passwordInput.fill(password);
// Agree to terms (checkbox-group)
const checkbox = page.locator('uni-checkbox, .checkbox').first();
const isChecked = await checkbox.getAttribute('checked').catch(() => null);
if (!isChecked || isChecked === 'false') {
await checkbox.click().catch(() => {
// Fallback: click the parent checkbox-group
return page.locator('uni-checkbox-group, .checkgroup').first().click();
});
}
// Click login button (current === 0 → "账号登录" button)
const loginBtn = page.locator('.logon').first();
await loginBtn.click();
// Wait for navigation away from login page
await page.waitForTimeout(3000);
}
/**
* Wait until the UniApp page finishes mounting (title or key element appears).
*/
export async function waitForPageReady(page: Page, selector: string, timeout = 10_000): Promise<void> {
await page.locator(selector).waitFor({ state: 'visible', timeout });
}