R7E 无人工操作自动化证据回填

这个提交包含在:
2026-05-14 16:09:38 +08:00
父节点 5afb8f9ab1
当前提交 b437743ef1
共修改 6 个文件,包含 408 行新增和 110 行删除
+42
查看文件
@@ -157,6 +157,48 @@ export async function createAuthenticatedApiClient(user: E2EUser, baseURL = E2E_
};
}
export async function createAuthenticatedBrowserStorageState(user: E2EUser, baseURL = E2E_BASE_URL) {
const deviceFingerprint = buildDeviceFingerprint(user);
const loginContext = await playwrightRequest.newContext({
baseURL,
extraHTTPHeaders: {
"x-device-fingerprint": deviceFingerprint,
},
});
try {
const loginResponse = await loginContext.post("/api/auth/login", {
data: {
identifier: user.identifier,
password: user.password,
},
});
await readJson<{ accessToken: string }>(loginResponse);
const state = await loginContext.storageState();
const origin = new URL(baseURL).origin;
const originState = state.origins.find((item) => item.origin === origin);
const deviceFingerprintEntry = {
name: "hyb_oa_device_fingerprint",
value: deviceFingerprint,
};
if (originState) {
originState.localStorage = originState.localStorage.filter((item) => item.name !== deviceFingerprintEntry.name);
originState.localStorage.push(deviceFingerprintEntry);
} else {
state.origins.push({
origin,
localStorage: [deviceFingerprintEntry],
});
}
return state;
} finally {
await loginContext.dispose();
}
}
export async function apiGetData<T>(api: APIRequestContext, path: string) {
const response = await api.get(path);
return readJson<T>(response);
+12 -2
查看文件
@@ -1,6 +1,6 @@
import { expect, type Page } from "@playwright/test";
import { createAuthenticatedApiClient, logout, type AuthenticatedApiClient, type E2EUser } from "./auth";
import { createAuthenticatedApiClient, createAuthenticatedBrowserStorageState, logout, type AuthenticatedApiClient, type E2EUser } from "./auth";
export type LiveSmokeRole = "admin" | "employee" | "manager" | "finance" | "financeMgr";
@@ -19,6 +19,11 @@ function requireEnv(key: string) {
return value;
}
function liveUrl(pathname: string) {
const baseURL = process.env.LIVE_SMOKE_BASE_URL?.trim();
return baseURL ? new URL(pathname, baseURL).toString() : pathname;
}
export function getExpectedWecomStatus() {
return process.env.LIVE_EXPECT_WECOM_STATUS?.trim() || "disabled";
}
@@ -68,7 +73,7 @@ async function readCurrentUserName(page: Page): Promise<string> {
export async function loginLiveUser(page: Page, role: LiveSmokeRole): Promise<LiveSmokeUser> {
const credentials = getLiveSmokeUser(role);
await page.goto("/login");
await page.goto(liveUrl("/login"));
await expect(page.getByTestId("login-identifier")).toBeVisible();
await page.getByTestId("login-identifier").fill(credentials.identifier);
await page.getByTestId("login-password").fill(credentials.password);
@@ -112,3 +117,8 @@ export async function createLiveApiClient(role: LiveSmokeRole): Promise<Authenti
const baseURL = process.env.LIVE_SMOKE_BASE_URL?.trim() || "https://oa.hyinda.com";
return createAuthenticatedApiClient(getRequiredLiveUser(role), baseURL);
}
export async function createLiveBrowserStorageState(role: LiveSmokeRole) {
const baseURL = process.env.LIVE_SMOKE_BASE_URL?.trim() || "https://oa.hyinda.com";
return createAuthenticatedBrowserStorageState(getRequiredLiveUser(role), baseURL);
}