feat: 集成 KieAI 服务,移除 models-integration 子项目
- 添加 Gemini 2.5 Flash 对话接口(流式+非流式) - 添加 NanoBanana 图像生成/编辑接口 - 添加 Sora2 视频生成接口(文生视频、图生视频、去水印) - 移除 models-integration 子项目(功能已迁移至主后端) - 新增测试文档和 Playwright E2E 配置 - 更新前端页面和 API 接口 - 更新后端配置和日志处理
This commit is contained in:
77
tests/e2e/helpers/app-helpers.ts
Normal file
77
tests/e2e/helpers/app-helpers.ts
Normal file
@@ -0,0 +1,77 @@
|
||||
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 });
|
||||
}
|
||||
Reference in New Issue
Block a user