修正 OALAUNCH1 登录与业务流回归(05-28-oalaunch1-parallel-closeout)

这个提交包含在:
2026-05-28 16:23:56 +08:00
父节点 c8b41a4056
当前提交 c30e2b1348
共修改 9 个文件,包含 162 行新增和 53 行删除
@@ -1,8 +1,50 @@
import { devices, expect, test } from "@playwright/test";
import { createAuthenticatedApiClient, MANAGER, type E2EUser } from "./helpers/auth";
import { createSubmittedTravelRequestViaApi } from "./helpers/travel";
import { apiGetData, apiPostData, createAuthenticatedApiClient, EMPLOYEE, MANAGER, type E2EUser } from "./helpers/auth";
import { approveWorkflowTaskViaApi, waitForWorkflowTask } from "./helpers/workflow";
type LeaveTypeListResponse = {
items: Array<{ id: string; requiresAttachment: boolean }>;
};
type WorkflowSubmitResponse = {
workflowInstanceId: string;
};
function formatDate(offsetDays: number) {
const value = new Date();
value.setUTCDate(value.getUTCDate() + offsetDays);
return value.toISOString().slice(0, 10);
}
async function createSubmittedLeaveViaApi(input: { reasonPrefix: string }) {
const client = await createAuthenticatedApiClient(EMPLOYEE);
const leaveTypes = await apiGetData<LeaveTypeListResponse>(client.api, "/api/leave-types?enabled=true");
const leaveType = leaveTypes.items.find((item) => !item.requiresAttachment) ?? leaveTypes.items[0];
if (!leaveType) {
throw new Error("缺少可用于移动审批离线测试的请假类型");
}
const offset = 3600 + (Date.now() % 1200);
const startDate = formatDate(offset);
const created = await apiPostData<{ id: string }>(client.api, "/api/leave-requests", {
leaveTypeId: leaveType.id,
startDate,
endDate: startDate,
startSession: "am",
endSession: "pm",
reason: `${input.reasonPrefix}-${Date.now()}`,
});
await apiPostData<WorkflowSubmitResponse>(client.api, `/api/leave-requests/${created.id}/submit`, {});
return {
client,
leaveRequest: {
requestId: created.id,
startDate,
},
};
}
async function loginMobile(page: import("@playwright/test").Page, user: E2EUser) {
await page.goto("/login");
await page.getByTestId("login-identifier").fill(user.identifier);
@@ -62,23 +104,22 @@ test.use({
});
test("E2E 移动审批:deep link 分流 + 离线草稿重放", async ({ page }) => {
const created = await createSubmittedTravelRequestViaApi({
purposePrefix: "Playwright移动审批通过",
amount: "999.00",
const created = await createSubmittedLeaveViaApi({
reasonPrefix: "Playwright移动审批通过",
});
const managerApi = await createAuthenticatedApiClient(MANAGER);
try {
const task = await waitForWorkflowTask(managerApi.api, {
entityId: created.travelRequest.requestId,
entityType: "travel_request",
entityId: created.leaveRequest.requestId,
entityType: "leave",
});
await loginMobile(page, MANAGER);
await page.goto(`/workflow/tasks/${task.id}`);
await expectMobileApprovalDetailUrl(page, task.id);
await expect(page.getByTestId("mobile-approvals-detail")).toBeVisible({ timeout: 30_000 });
await expect(page.getByTestId("mobile-approvals-detail")).toContainText(created.travelRequest.requestNo);
await expect(page.getByTestId("mobile-approvals-detail")).toContainText("请假");
await waitForWorkflowTaskCache(page, task.id);
await page.context().setOffline(true);
@@ -98,23 +139,22 @@ test("E2E 移动审批:deep link 分流 + 离线草稿重放", async ({ page }
});
test("E2E 移动审批:离线草稿冲突态可见", async ({ page }) => {
const created = await createSubmittedTravelRequestViaApi({
purposePrefix: "Playwright移动审批冲突",
amount: "1099.00",
const created = await createSubmittedLeaveViaApi({
reasonPrefix: "Playwright移动审批冲突",
});
const managerApi = await createAuthenticatedApiClient(MANAGER);
try {
const task = await waitForWorkflowTask(managerApi.api, {
entityId: created.travelRequest.requestId,
entityType: "travel_request",
entityId: created.leaveRequest.requestId,
entityType: "leave",
});
await loginMobile(page, MANAGER);
await page.goto(`/workflow/tasks/${task.id}`);
await expectMobileApprovalDetailUrl(page, task.id);
await expect(page.getByTestId("mobile-approvals-detail")).toBeVisible({ timeout: 30_000 });
await expect(page.getByTestId("mobile-approvals-detail")).toContainText(created.travelRequest.requestNo);
await expect(page.getByTestId("mobile-approvals-detail")).toContainText("请假");
await waitForWorkflowTaskCache(page, task.id);
await page.context().setOffline(true);