R7E 真机二次反馈移动修复

引用 R7E-16C BIZ8-12B
这个提交包含在:
2026-05-15 18:24:03 +08:00
父节点 8cd4b92857
当前提交 f945c0bfb0
共修改 10 个文件,包含 197 行新增和 24 行删除
@@ -778,6 +778,74 @@ async function expectNoMobileShellRegression(page: Page) {
expect(metrics.clippedStatusSlots).toEqual([]);
}
async function expectMobileApprovalStatusSlots(page: Page) {
const slots = await page.evaluate(() =>
Array.from(document.querySelectorAll<HTMLElement>(".mobile-status-slot--approval"))
.filter((slot) => {
const rect = slot.getBoundingClientRect();
const style = getComputedStyle(slot);
return rect.width > 0 && rect.height > 0 && style.visibility !== "hidden" && style.display !== "none";
})
.map((slot) => {
const rect = slot.getBoundingClientRect();
const badge = slot.querySelector<HTMLElement>(".mobile-status-badge");
const badgeRect = badge?.getBoundingClientRect();
return {
text: slot.innerText.trim(),
width: rect.width,
badgeWidth: badgeRect?.width ?? 0,
};
}),
);
expect(slots.length).toBeGreaterThan(0);
for (const slot of slots) {
expect(slot.text.length).toBeGreaterThanOrEqual(2);
expect(slot.width).toBeGreaterThanOrEqual(54);
expect(slot.badgeWidth).toBeGreaterThanOrEqual(54);
}
}
async function expectMobileDetailHeaderSpacing(page: Page, testId: string) {
const metrics = await page.getByTestId(testId).evaluate((header) => {
const backButton = header.querySelector<HTMLElement>("button[aria-label='返回']");
const title = header.querySelector<HTMLElement>(".mobile-detail-header__title");
const backRect = backButton?.getBoundingClientRect();
const titleRect = title?.getBoundingClientRect();
return backRect && titleRect ? {
backWidth: backRect.width,
gap: titleRect.left - backRect.right,
} : null;
});
expect(metrics).not.toBeNull();
expect(metrics!.backWidth).toBeGreaterThanOrEqual(44);
expect(metrics!.gap).toBeGreaterThanOrEqual(12);
}
async function expectApprovalActionsStable(page: Page) {
const actions = await page.evaluate(() =>
Array.from(document.querySelectorAll<HTMLElement>(".mobile-approval-action-grid > button")).map((button) => {
const rect = button.getBoundingClientRect();
return {
left: rect.left,
right: rect.right,
top: rect.top,
width: rect.width,
};
}),
);
expect(actions).toHaveLength(3);
const firstTop = actions[0].top;
for (const action of actions) {
expect(Math.abs(action.top - firstTop)).toBeLessThanOrEqual(2);
expect(action.width).toBeGreaterThanOrEqual(64);
}
expect(actions[0].right).toBeLessThanOrEqual(actions[1].left + 2);
expect(actions[1].right).toBeLessThanOrEqual(actions[2].left + 2);
}
async function expectActionTileGapStable(page: Page) {
const gaps = await page.evaluate(() =>
Array.from(document.querySelectorAll<HTMLElement>("[data-testid='mobile-action-grid'] .mobile-icon-action")).map((tile) => {
@@ -843,6 +911,7 @@ test.describe("MIF7 移动信息架构整改", () => {
await expect(mobile.page.getByTestId("mobile-approvals-list")).toHaveCount(0);
await expect(mobile.page.getByTestId("mobile-approvals-approve")).toHaveCount(0);
await expect(mobile.page.getByTestId("mobile-approval-progress-card")).toHaveCount(3);
await expectMobileApprovalStatusSlots(mobile.page);
await expectNoMobileShellRegression(mobile.page);
await mobile.page.screenshot({ path: screenshotPath(`employee-progress-w${width}`), fullPage: true });
@@ -908,6 +977,9 @@ test.describe("MIF7 移动信息架构整改", () => {
await expect(mobile.page.getByTestId("mobile-approvals-history")).toContainText("提交 · 测试员工");
await expect(mobile.page.getByTestId("mobile-approvals-history")).toContainText("转审 · 测试审批人");
await expect(mobile.page.getByTestId("mobile-approvals-history")).not.toContainText("transferToEmployeeId");
await expectMobileApprovalStatusSlots(mobile.page);
await expectMobileDetailHeaderSpacing(mobile.page, "mobile-approvals-detail-header");
await expectApprovalActionsStable(mobile.page);
await expectNoMobileShellRegression(mobile.page);
await mobile.page.screenshot({ path: screenshotPath("manager-approval-push-detail"), fullPage: true });
@@ -1050,6 +1122,10 @@ test.describe("MIF7 移动信息架构整改", () => {
await financeMobile.page.screenshot({ path: screenshotPath("home-finance-summary"), fullPage: true });
await financeMobile.page.goto("/mobile/me");
await expect(financeMobile.page.getByRole("link", { name: /财务/ })).toBeVisible();
await financeMobile.page.getByRole("link", { name: /财务/ }).click();
await expect(financeMobile.page).toHaveURL(/\/mobile#finance$/);
await expect(financeMobile.page.getByTestId("mobile-finance-summary")).toBeInViewport();
await expect(financeMobile.page.getByTestId("mobile-finance-disabled-state")).toBeInViewport();
await expectNoMobileShellRegression(financeMobile.page);
} finally {
await financeMobile.context.close();
@@ -55,7 +55,7 @@ function buildMe() {
directManagerId: null,
status: "active",
notificationPushEnabled: true,
roleCodes: ["manager"],
roleCodes: ["manager", "finance"],
profileCompleteness: {
hasEmergencyContact: true,
hasBankAccount: true,
@@ -230,6 +230,13 @@ async function mockApis(page: Page, state: ReturnType<typeof buildState>) {
weeklySummary: null,
todoSummary: null,
projectSummary: null,
financeSummary: {
paymentBatchEnabled: false,
href: "/mobile#finance",
pendingBatchCount: 0,
failedItemCount: 0,
riskCount: 0,
},
peopleLifecycle: null,
adoptionSummary: null,
recentActivities: [],
@@ -518,6 +525,7 @@ test.describe("R124 企业微信移动入口矩阵", () => {
await mobile.page.getByTestId("mobile-nav-approvals").click();
await expect(mobile.page).toHaveURL(/\/mobile\/approvals$/);
await expect(mobile.page.getByText("审批").first()).toBeVisible();
await expect(mobile.page.locator(".mobile-status-slot--approval").first()).toContainText("待处理");
await expectMobilePageContract(mobile.page);
await mobile.page.getByTestId("mobile-nav-me").click();
@@ -526,6 +534,14 @@ test.describe("R124 企业微信移动入口矩阵", () => {
await mobile.page.screenshot({ path: screenshotPath("mobile-me") });
await expectMobilePageContract(mobile.page);
await expect(mobile.page.getByRole("link", { name: /财务/ })).toBeVisible();
await mobile.page.getByRole("link", { name: /财务/ }).click();
await expect(mobile.page).toHaveURL(/\/mobile#finance$/);
await expect(mobile.page.getByTestId("mobile-finance-summary")).toBeInViewport();
await expect(mobile.page.getByTestId("mobile-finance-disabled-state")).toBeInViewport();
await expectMobilePageContract(mobile.page);
await mobile.page.goto("/mobile/me");
await mobile.page.getByRole("link", { name: /个人设置/ }).click();
await expect(mobile.page).toHaveURL(/\/mobile\/profile$/);
await expect(mobile.page.getByTestId("mobile-profile-page")).toBeVisible();