R7E 无人工操作自动化证据回填
这个提交包含在:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
在新工单中引用
屏蔽一个用户