完成五人团队正式内用最小收口(07-18-small-team-internal-readiness)
这个提交包含在:
@@ -7,6 +7,10 @@ import { expect, test } from "./helpers/fixtures";
|
||||
test.use({ serviceWorkers: "block" });
|
||||
|
||||
const outputDir = path.resolve(process.cwd(), "../output/playwright/pc-detail-mobile-visual-wave3");
|
||||
const taskOutputDir = path.resolve(
|
||||
process.cwd(),
|
||||
"../output/playwright/07-18-small-team-internal-readiness",
|
||||
);
|
||||
|
||||
const visualUser = {
|
||||
identifier: "[email protected]",
|
||||
@@ -400,6 +404,18 @@ const contractRegistryItem = {
|
||||
project: { id: projectDetail.id, projectNo: projectDetail.projectNo, name: projectDetail.name },
|
||||
};
|
||||
|
||||
const secondContractRegistryItem = {
|
||||
...contractRegistryItem,
|
||||
id: "contract-wave3-second",
|
||||
contractNo: "HT-2026-W3-02",
|
||||
counterpartyName: "上海合成技术服务有限公司",
|
||||
summary: "用于验证合同记录切换保护的第二条合成台账",
|
||||
amount: "18000.00",
|
||||
expiryDate: "2026-07-20",
|
||||
archiveLocation: "离线档案柜 A-02",
|
||||
offlineArchiveNo: "OFF-2026-W3-02",
|
||||
};
|
||||
|
||||
const purchaseDetail = {
|
||||
id: "purchase-wave3",
|
||||
requestNo: "CG20260527001",
|
||||
@@ -510,6 +526,11 @@ function screenshotPath(fileName: string) {
|
||||
return path.join(outputDir, fileName);
|
||||
}
|
||||
|
||||
function taskScreenshotPath(fileName: string) {
|
||||
mkdirSync(taskOutputDir, { recursive: true });
|
||||
return path.join(taskOutputDir, fileName);
|
||||
}
|
||||
|
||||
function navigationItem(key: string, href: string, label: string, icon: string, placement = "main") {
|
||||
return { key, href, label, icon, placement, permissionCodes: [], featureFlagKey: null };
|
||||
}
|
||||
@@ -901,7 +922,7 @@ async function mockWave3Apis(page: Page) {
|
||||
}
|
||||
|
||||
if (pathName === "/api/contracts-registry") {
|
||||
await fulfillJson(route, { items: [contractRegistryItem] });
|
||||
await fulfillJson(route, { items: [contractRegistryItem, secondContractRegistryItem] });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1055,6 +1076,7 @@ test.beforeEach(async ({ page }) => {
|
||||
});
|
||||
|
||||
test("Wave3 PC 详情和通知中心视觉截图", async ({ page }) => {
|
||||
test.setTimeout(300_000);
|
||||
await page.setViewportSize({ width: 1440, height: 960 });
|
||||
|
||||
await page.goto("/reimbursements/reim-wave3");
|
||||
@@ -1099,7 +1121,9 @@ test("Wave3 PC 详情和通知中心视觉截图", async ({ page }) => {
|
||||
|
||||
await page.goto("/contracts-registry?projectId=project-wave3");
|
||||
await expect(page.getByRole("heading", { name: "合同", exact: true })).toBeVisible();
|
||||
await expect(page.getByTestId("contracts-registry-table").getByTestId("contracts-registry-row")).toBeVisible();
|
||||
const contractRows = page.getByTestId("contracts-registry-table").getByTestId("contracts-registry-row");
|
||||
await expect(contractRows).toHaveCount(2);
|
||||
await expect(contractRows.first()).toBeVisible();
|
||||
await page.locator(".ops-command-bar__actions").getByRole("button", { name: "更多" }).click();
|
||||
await expect(page.getByRole("menuitem", { name: "导出 CSV" })).toBeVisible();
|
||||
await page.keyboard.press("Escape");
|
||||
@@ -1108,7 +1132,7 @@ test("Wave3 PC 详情和通知中心视觉截图", async ({ page }) => {
|
||||
await page.getByRole("button", { name: "新增合同" }).click();
|
||||
await expect(page.getByTestId("contracts-editor-panel")).toBeVisible();
|
||||
await page.getByRole("button", { name: "关闭" }).click();
|
||||
await expect(page.getByTestId("contracts-registry-table").getByTestId("contracts-registry-row")).toBeVisible();
|
||||
await expect(contractRows).toHaveCount(2);
|
||||
await page.getByTestId("contracts-registry-table").getByRole("button", { name: "更多" }).first().click();
|
||||
await page.getByRole("menuitem", { name: "归档" }).click();
|
||||
await expect(page.getByTestId("action-confirm-dialog")).toContainText("确认归档");
|
||||
@@ -1117,6 +1141,59 @@ test("Wave3 PC 详情和通知中心视觉截图", async ({ page }) => {
|
||||
await page.screenshot({ path: screenshotPath("04-pc-contracts-registry.png"), fullPage: true });
|
||||
});
|
||||
|
||||
test("/contracts-registry 在 768x1024 与 1024x768 下操作列可达", async ({ page }) => {
|
||||
for (const viewport of [
|
||||
{ width: 768, height: 1024 },
|
||||
{ width: 1024, height: 768 },
|
||||
]) {
|
||||
await page.setViewportSize(viewport);
|
||||
await page.goto("/contracts-registry");
|
||||
await expect(page.getByRole("heading", { name: "合同", exact: true })).toBeVisible();
|
||||
const table = page.getByTestId("contracts-registry-table");
|
||||
await expect(table).toBeVisible();
|
||||
const scrollRegion = table.locator("xpath=ancestor::*[@data-testid='business-table-scroll']").first();
|
||||
const metrics = await scrollRegion.evaluate((element) => {
|
||||
element.scrollLeft = element.scrollWidth;
|
||||
return {
|
||||
overflowX: window.getComputedStyle(element).overflowX,
|
||||
clientWidth: element.clientWidth,
|
||||
scrollWidth: element.scrollWidth,
|
||||
documentOverflow: document.documentElement.scrollWidth - document.documentElement.clientWidth,
|
||||
};
|
||||
});
|
||||
expect(["auto", "scroll"]).toContain(metrics.overflowX);
|
||||
expect(metrics.scrollWidth).toBeGreaterThanOrEqual(metrics.clientWidth);
|
||||
expect(metrics.documentOverflow).toBeLessThanOrEqual(2);
|
||||
const operation = table.getByRole("button", { name: "更多" }).first();
|
||||
await expect(operation).toBeVisible();
|
||||
await operation.click({ trial: true });
|
||||
await page.screenshot({
|
||||
path: taskScreenshotPath(`contracts-registry-${viewport.width}x${viewport.height}.png`),
|
||||
fullPage: true,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test("合同长表单从记录 A 切换到记录 B 时支持取消保持与确认放弃", async ({ page }) => {
|
||||
await page.setViewportSize({ width: 1280, height: 900 });
|
||||
await page.goto("/contracts-registry");
|
||||
const table = page.getByTestId("contracts-registry-table");
|
||||
const editButtons = table.getByRole("button", { name: "编辑", exact: true });
|
||||
await editButtons.first().click();
|
||||
const counterparty = page.getByPlaceholder("合同对方名称");
|
||||
await counterparty.fill("合成未保存合同相对方");
|
||||
|
||||
await editButtons.nth(1).click();
|
||||
await expect(page.getByTestId("unsaved-changes-dialog")).toContainText("合同表单尚未保存");
|
||||
await page.getByTestId("unsaved-changes-continue").click();
|
||||
await expect(page).toHaveURL(/\/contracts-registry$/);
|
||||
await expect(counterparty).toHaveValue("合成未保存合同相对方");
|
||||
|
||||
await editButtons.nth(1).click();
|
||||
await page.getByTestId("unsaved-changes-discard").click();
|
||||
await expect(counterparty).toHaveValue(secondContractRegistryItem.counterpartyName);
|
||||
});
|
||||
|
||||
test("Wave3 移动关键页视觉截图", async ({ page }) => {
|
||||
await page.setViewportSize({ width: 390, height: 844 });
|
||||
|
||||
|
||||
在新工单中引用
屏蔽一个用户