R36-1/R36-2/R36-3/R36-5 收口请假编辑与团队日历
这个提交包含在:
@@ -1,8 +1,8 @@
|
||||
import { expect, test, type Page } from "@playwright/test";
|
||||
|
||||
import { EMPLOYEE, login, type E2EUser } from "./helpers/auth";
|
||||
import { EMPLOYEE, MANAGER, login, type E2EUser } from "./helpers/auth";
|
||||
|
||||
const LEAVE_CALENDAR_MANAGER: E2EUser = {
|
||||
const LEAVE_CALENDAR_HR: E2EUser = {
|
||||
identifier: "[email protected]",
|
||||
password: "HrPassword1234",
|
||||
name: "HR",
|
||||
@@ -149,7 +149,12 @@ function buildCalendarItems(dateFrom: string, dateTo: string) {
|
||||
}
|
||||
|
||||
async function mockLeaveRequests(page: Page) {
|
||||
const observedCalendarQueries: Array<{ dateFrom: string; dateTo: string; pageSize: string }> = [];
|
||||
const observedCalendarQueries: Array<{
|
||||
dateFrom: string;
|
||||
dateTo: string;
|
||||
pageSize: string;
|
||||
departmentId: string | null;
|
||||
}> = [];
|
||||
|
||||
await page.route("**/api/leave-requests?**", async (route) => {
|
||||
const url = new URL(route.request().url());
|
||||
@@ -157,9 +162,10 @@ async function mockLeaveRequests(page: Page) {
|
||||
const pageSize = url.searchParams.get("pageSize") ?? "10";
|
||||
const dateFrom = url.searchParams.get("dateFrom");
|
||||
const dateTo = url.searchParams.get("dateTo");
|
||||
const departmentId = url.searchParams.get("departmentId");
|
||||
|
||||
if (scope === "all" && dateFrom && dateTo) {
|
||||
observedCalendarQueries.push({ dateFrom, dateTo, pageSize });
|
||||
observedCalendarQueries.push({ dateFrom, dateTo, pageSize, departmentId });
|
||||
await route.fulfill({
|
||||
status: 200,
|
||||
contentType: "application/json",
|
||||
@@ -194,10 +200,10 @@ async function mockLeaveRequests(page: Page) {
|
||||
return observedCalendarQueries;
|
||||
}
|
||||
|
||||
test("E2E 请假团队日历:具备团队查看权限的用户可见周/月视图并显示截断提示", async ({ page }) => {
|
||||
test("E2E 请假团队日历:HR 可见全员周/月视图并显示截断提示", async ({ page }) => {
|
||||
const observedCalendarQueries = await mockLeaveRequests(page);
|
||||
|
||||
await login(page, LEAVE_CALENDAR_MANAGER);
|
||||
await login(page, LEAVE_CALENDAR_HR);
|
||||
await page.goto("/leave-requests");
|
||||
|
||||
await expect(page.getByRole("heading", { name: "请假申请" })).toBeVisible();
|
||||
@@ -229,6 +235,82 @@ test("E2E 请假团队日历:具备团队查看权限的用户可见周/月视
|
||||
await expect.poll(() => observedCalendarQueries.length).toBeGreaterThanOrEqual(2);
|
||||
expect(observedCalendarQueries.every((query) => Boolean(query.dateFrom && query.dateTo))).toBe(true);
|
||||
expect(observedCalendarQueries.every((query) => query.pageSize === "100")).toBe(true);
|
||||
expect(observedCalendarQueries.every((query) => query.departmentId == null)).toBe(true);
|
||||
});
|
||||
|
||||
test("E2E 请假团队日历:经理只拉本部门数据且导航会触发新查询", async ({ page }) => {
|
||||
const observedCalendarQueries = await mockLeaveRequests(page);
|
||||
|
||||
await login(page, MANAGER);
|
||||
await page.goto("/leave-requests");
|
||||
|
||||
await expect(page.getByRole("heading", { name: "请假申请" })).toBeVisible();
|
||||
await expect(page.getByTestId("leave-view-calendar")).toBeVisible();
|
||||
|
||||
const firstResponse = page.waitForResponse((response) => {
|
||||
const url = new URL(response.url());
|
||||
return response.ok() && url.pathname === "/api/leave-requests" && url.searchParams.get("scope") === "all";
|
||||
});
|
||||
await page.getByTestId("leave-view-calendar").click();
|
||||
await firstResponse;
|
||||
|
||||
await expect(page.getByTestId("leave-team-calendar-grid")).toBeVisible();
|
||||
await expect(page.getByTestId("leave-team-calendar-entry").filter({ hasText: "王小明" }).first()).toBeVisible();
|
||||
await expect.poll(() => observedCalendarQueries.length).toBeGreaterThanOrEqual(1);
|
||||
expect(observedCalendarQueries.every((query) => Boolean(query.departmentId))).toBe(true);
|
||||
|
||||
const firstQuery = observedCalendarQueries.at(-1);
|
||||
if (!firstQuery) {
|
||||
throw new Error("经理团队日历未记录到首个查询");
|
||||
}
|
||||
|
||||
const previousResponse = page.waitForResponse((response) => {
|
||||
const url = new URL(response.url());
|
||||
return response.ok() && url.pathname === "/api/leave-requests" && url.searchParams.get("scope") === "all";
|
||||
});
|
||||
await page.getByTestId("leave-calendar-prev").click();
|
||||
await previousResponse;
|
||||
|
||||
const previousQuery = observedCalendarQueries.at(-1);
|
||||
if (!previousQuery) {
|
||||
throw new Error("经理团队日历未记录到上一窗口查询");
|
||||
}
|
||||
expect(previousQuery.dateFrom).not.toBe(firstQuery.dateFrom);
|
||||
|
||||
const todayResponse = page.waitForResponse((response) => {
|
||||
const url = new URL(response.url());
|
||||
return response.ok() && url.pathname === "/api/leave-requests" && url.searchParams.get("scope") === "all";
|
||||
});
|
||||
await page.getByTestId("leave-calendar-today").click();
|
||||
await todayResponse;
|
||||
|
||||
const todayQuery = observedCalendarQueries.at(-1);
|
||||
if (!todayQuery) {
|
||||
throw new Error("经理团队日历未记录到今天查询");
|
||||
}
|
||||
expect(todayQuery.dateFrom).toBe(firstQuery.dateFrom);
|
||||
|
||||
const monthResponse = page.waitForResponse((response) => {
|
||||
const url = new URL(response.url());
|
||||
return response.ok() && url.pathname === "/api/leave-requests" && url.searchParams.get("scope") === "all";
|
||||
});
|
||||
await page.getByTestId("leave-calendar-mode-month").click();
|
||||
await monthResponse;
|
||||
|
||||
await expect.poll(() => page.getByTestId("leave-team-calendar-cell").count()).toBeGreaterThan(7);
|
||||
|
||||
const nextMonthResponse = page.waitForResponse((response) => {
|
||||
const url = new URL(response.url());
|
||||
return response.ok() && url.pathname === "/api/leave-requests" && url.searchParams.get("scope") === "all";
|
||||
});
|
||||
await page.getByTestId("leave-calendar-next").click();
|
||||
await nextMonthResponse;
|
||||
|
||||
const nextMonthQuery = observedCalendarQueries.at(-1);
|
||||
if (!nextMonthQuery) {
|
||||
throw new Error("经理团队日历未记录到下一窗口查询");
|
||||
}
|
||||
expect(nextMonthQuery.dateFrom).not.toBe(todayQuery.dateFrom);
|
||||
});
|
||||
|
||||
test("E2E 请假团队日历:员工视角不显示团队日历 Tab", async ({ page }) => {
|
||||
|
||||
在新工单中引用
屏蔽一个用户