修正 OALAUNCH1 登录与业务流回归(05-28-oalaunch1-parallel-closeout)
这个提交包含在:
@@ -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);
|
||||
|
||||
在新工单中引用
屏蔽一个用户