feat: prepare Zhinian desktop client for pilot release
This commit is contained in:
105
tests/e2e/yinian-visual-smoke.spec.ts
Normal file
105
tests/e2e/yinian-visual-smoke.spec.ts
Normal file
@@ -0,0 +1,105 @@
|
||||
import electronBinaryPath from 'electron';
|
||||
import { _electron as electron, test } from '@playwright/test';
|
||||
import { mkdir, mkdtemp, rm } from 'node:fs/promises';
|
||||
import { createServer } from 'node:net';
|
||||
import { tmpdir } from 'node:os';
|
||||
import { join, resolve } from 'node:path';
|
||||
import { pathToFileURL } from 'node:url';
|
||||
import { closeElectronApp, expect, getStableWindow } from './fixtures/electron';
|
||||
|
||||
const repoRoot = resolve(process.cwd());
|
||||
const electronEntry = join(repoRoot, 'dist-electron/main/index.js');
|
||||
const rendererEntry = pathToFileURL(join(repoRoot, 'dist/index.html')).toString();
|
||||
const screenshotDir = join(repoRoot, 'test-results', 'yinian-visual');
|
||||
|
||||
async function allocatePort(): Promise<number> {
|
||||
return await new Promise((resolvePort, reject) => {
|
||||
const server = createServer();
|
||||
server.once('error', reject);
|
||||
server.listen(0, '127.0.0.1', () => {
|
||||
const address = server.address();
|
||||
if (!address || typeof address === 'string') {
|
||||
server.close(() => reject(new Error('Failed to allocate an ephemeral port')));
|
||||
return;
|
||||
}
|
||||
|
||||
server.close((error) => {
|
||||
if (error) {
|
||||
reject(error);
|
||||
return;
|
||||
}
|
||||
resolvePort(address.port);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
test('captures the core Zhinian production UI surfaces', async () => {
|
||||
await mkdir(screenshotDir, { recursive: true });
|
||||
const homeDir = await mkdtemp(join(tmpdir(), 'zhinian-visual-home-'));
|
||||
const userDataDir = await mkdtemp(join(tmpdir(), 'zhinian-visual-user-data-'));
|
||||
const hostApiPort = await allocatePort();
|
||||
const electronEnv = process.platform === 'linux'
|
||||
? { ELECTRON_DISABLE_SANDBOX: '1' }
|
||||
: {};
|
||||
|
||||
const app = await electron.launch({
|
||||
executablePath: electronBinaryPath,
|
||||
args: [electronEntry],
|
||||
env: {
|
||||
...process.env,
|
||||
...electronEnv,
|
||||
HOME: homeDir,
|
||||
USERPROFILE: homeDir,
|
||||
APPDATA: join(homeDir, 'AppData', 'Roaming'),
|
||||
LOCALAPPDATA: join(homeDir, 'AppData', 'Local'),
|
||||
XDG_CONFIG_HOME: join(homeDir, '.config'),
|
||||
CLAWX_E2E: '1',
|
||||
CLAWX_USER_DATA_DIR: userDataDir,
|
||||
CLAWX_PORT_CLAWX_HOST_API: String(hostApiPort),
|
||||
VITE_DEV_SERVER_URL: '',
|
||||
},
|
||||
timeout: 90_000,
|
||||
});
|
||||
|
||||
try {
|
||||
const page = await getStableWindow(app);
|
||||
await page.setViewportSize({ width: 1440, height: 900 });
|
||||
|
||||
// The main process stays in E2E mode to avoid startup side effects, while
|
||||
// the renderer is reloaded without the e2e query so the production YINIAN
|
||||
// login and tenant flow are exercised.
|
||||
await page.goto(rendererEntry);
|
||||
await expect(page.getByTestId('yinian-login-page')).toBeVisible();
|
||||
await page.screenshot({ path: join(screenshotDir, '01-login.png'), fullPage: true });
|
||||
|
||||
await page.getByRole('textbox', { name: '账号' }).fill('admin');
|
||||
await page.locator('#password').fill('123456');
|
||||
const captchaInput = page.getByLabel('图形验证码');
|
||||
if (await captchaInput.count()) {
|
||||
await captchaInput.fill('5678');
|
||||
}
|
||||
await page.getByRole('button', { name: /^登录$/ }).click();
|
||||
await expect(page.getByTestId('today-page')).toBeVisible();
|
||||
await page.getByTestId('sidebar-chat-history').hover();
|
||||
await expect(page.getByTestId('sidebar-chat-history-popover')).toBeVisible();
|
||||
await page.screenshot({ path: join(screenshotDir, '02-today.png'), fullPage: true });
|
||||
|
||||
await page.getByTestId('sidebar-nav-skills').click();
|
||||
await expect(page.getByTestId('yinian-skills-page')).toBeVisible();
|
||||
await page.screenshot({ path: join(screenshotDir, '03-skills.png'), fullPage: true });
|
||||
|
||||
await page.getByTestId('sidebar-nav-knowledge').click();
|
||||
await expect(page.getByTestId('knowledge-page')).toBeVisible();
|
||||
await page.screenshot({ path: join(screenshotDir, '04-knowledge.png'), fullPage: true });
|
||||
|
||||
await page.getByTestId('sidebar-nav-settings').click();
|
||||
await expect(page.getByTestId('settings-page')).toBeVisible();
|
||||
await expect(page.getByTestId('settings-service-section')).toBeVisible();
|
||||
await page.screenshot({ path: join(screenshotDir, '05-settings.png'), fullPage: true });
|
||||
} finally {
|
||||
await closeElectronApp(app);
|
||||
await rm(homeDir, { recursive: true, force: true });
|
||||
await rm(userDataDir, { recursive: true, force: true });
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user