import { mkdirSync } from "node:fs"; import path from "node:path"; import { expect, test, type Page } from "@playwright/test"; import { getExpectedWecomStatus, loginLiveUser, logoutLiveUser } from "./helpers/liveAuth"; import { fetchWecomConfig } from "./helpers/smokeAssertions"; const screenshotDir = path.resolve(process.cwd(), "../output/playwright/r104"); const WECOM_UA = "Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/15E148 wxwork/4.1.20 MicroMessenger/8.0.1 Language/zh_CN"; function screenshotPath(fileName: string) { mkdirSync(screenshotDir, { recursive: true }); return path.join(screenshotDir, fileName); } async function expectNoDesignRegressionCopy(page: Page) { const bodyText = await page.locator("body").innerText(); expect(bodyText).not.toContain("先处理这几件事"); expect(bodyText).not.toContain("清爽"); expect(bodyText).not.toContain("/invoice-pool"); expect(bodyText).not.toContain("/purchase-requests"); } test.describe("R104 public visual acceptance", () => { test.skip(process.env.E2E_MODE !== "live", "仅在公网 live 模式下执行"); test("公网桌面登录页与企业微信配置可见", async ({ page }) => { await page.setViewportSize({ width: 1440, height: 960 }); await page.goto("/login"); await expect(page.getByTestId("login-identifier")).toBeVisible(); await expect(page.getByTestId("login-password")).toBeVisible(); await expect(page.getByTestId("login-submit")).toBeVisible(); await expect(page.getByTestId("wecom-entry-browser-notice")).toBeVisible(); await expect(page.getByTestId("wecom-entry-browser-notice")).toContainText("企业微信一键进入"); const wecomConfig = await fetchWecomConfig(page); expect(wecomConfig.status).toBe(200); expect(wecomConfig.data?.status).toBe(getExpectedWecomStatus()); expect(wecomConfig.data?.defaultReturnTo).toBe("/mobile"); expect(wecomConfig.data?.loginUrl).toContain("returnTo=%2Fmobile"); await expectNoDesignRegressionCopy(page); await page.screenshot({ path: screenshotPath("desktop-login.png"), fullPage: true }); }); test("公网企业微信 WebView 入口跳转到 OAuth 边界", async ({ browser }) => { const context = await browser.newContext({ viewport: { width: 390, height: 844 }, isMobile: true, hasTouch: true, userAgent: WECOM_UA, locale: "zh-CN", serviceWorkers: "block", }); const page = await context.newPage(); await page.goto("/login"); await expect(page.getByTestId("wecom-entry-primary")).toBeVisible(); await page.screenshot({ path: screenshotPath("mobile-login-before-wecom.png"), fullPage: true }); await page.getByTestId("wecom-entry-primary").click(); await expect(page).toHaveURL(/open\.weixin\.qq\.com|work\.weixin\.qq\.com|wechat_redirect/); await context.close(); }); test("公网员工移动工作台与高频页面保持移动体验", async ({ page }) => { await page.setViewportSize({ width: 390, height: 844 }); await loginLiveUser(page, "employee"); await page.goto("/mobile"); await expect(page.getByTestId("mobile-nav-home")).toBeVisible(); await expect(page.getByTestId("mobile-nav-approvals")).toBeVisible(); await expect(page.getByTestId("mobile-nav-reimbursements")).toBeVisible(); await expect(page.getByTestId("mobile-nav-me")).toBeVisible(); await expectNoDesignRegressionCopy(page); await page.screenshot({ path: screenshotPath("mobile-home.png"), fullPage: true }); await page.goto("/mobile/reimbursements"); await expect(page.locator("table")).toHaveCount(0); await expectNoDesignRegressionCopy(page); await page.screenshot({ path: screenshotPath("mobile-reimbursements.png"), fullPage: true }); await page.goto("/mobile/leave"); await expect(page.locator("table")).toHaveCount(0); await expectNoDesignRegressionCopy(page); await page.screenshot({ path: screenshotPath("mobile-leave.png"), fullPage: true }); }); test("公网 PC 报销与票据页面不回退到路径式标题", async ({ page }) => { await page.setViewportSize({ width: 1440, height: 960 }); const employee = await loginLiveUser(page, "employee"); await page.goto("/reimbursements"); await expect(page.getByRole("heading", { name: /报销/ })).toBeVisible(); await expectNoDesignRegressionCopy(page); await page.screenshot({ path: screenshotPath("desktop-reimbursements.png"), fullPage: true }); await page.goto("/invoice-pool"); await expect(page.getByRole("heading", { name: "票据", exact: true })).toBeVisible(); await expectNoDesignRegressionCopy(page); await page.screenshot({ path: screenshotPath("desktop-invoice-pool.png"), fullPage: true }); await logoutLiveUser(page, employee); }); });