fix(detail-page-structure-progress-actions): 收敛操作面板定位并补充制单诊断
ci-e2e / e2e (push) Canceled after 0s
ci-minimal / check-minimal (push) Canceled after 0s

这个提交包含在:
2026-08-03 16:41:32 +08:00
父节点 59e91b8789
当前提交 a5b7e18507
共修改 8 个文件,包含 147 行新增和 12 行删除
@@ -88,9 +88,19 @@ describe("payment order BIFF8 generator", () => {
});
it("fails closed when the fixed Python runtime is unavailable", () => {
expect(() => generatePaymentOrderXls(config, buildBatch(), {
pythonBin: "/definitely-missing/payment-order-python",
})).toThrow(expect.objectContaining({ code: "payment_order_generator_unavailable" }));
let caught;
try {
generatePaymentOrderXls(config, buildBatch(), {
pythonBin: "/definitely-missing/payment-order-python",
});
} catch (error) {
caught = error;
}
expect(caught).toBeInstanceOf(PaymentOrderXlsError);
expect(caught).toMatchObject({ code: "payment_order_generator_unavailable" });
expect(caught.diagnostic).toContain("server/requirements/payment-order-biff8.txt");
expect(caught.diagnostic).toContain("PAYMENT_ORDER_PYTHON_BIN");
expect(JSON.stringify(caught)).not.toContain("payment-order-biff8.txt");
});
it("fails closed when the fixed Python dependencies are unavailable", () => {
@@ -102,8 +112,15 @@ describe("payment order BIFF8 generator", () => {
"#!/bin/sh\nprintf '%s\\n' '[payment-order-template][ERROR] runtime_dependency_unavailable' >&2\nexit 70\n",
{ mode: 0o700 },
);
expect(() => generatePaymentOrderXls(config, buildBatch(), { pythonBin: fakePython }))
.toThrow(expect.objectContaining({ code: "payment_order_generator_unavailable" }));
let caught;
try {
generatePaymentOrderXls(config, buildBatch(), { pythonBin: fakePython });
} catch (error) {
caught = error;
}
expect(caught).toMatchObject({ code: "payment_order_generator_unavailable" });
expect(caught.diagnostic).toContain("server/requirements/payment-order-biff8.txt");
expect(JSON.stringify(caught)).not.toContain("PAYMENT_ORDER_PYTHON_BIN");
} finally {
fs.rmSync(temporaryRoot, { recursive: true, force: true });
}
@@ -117,6 +117,28 @@ describe("paymentProcessingProgress", () => {
expect(assembler).not.toContain('label: "付款完成"');
}
});
it("keeps workflow action stacking local while the shared panel owns sticky positioning", () => {
const templateSource = fs.readFileSync(
path.resolve(__dirname, "../../../../client/src/components/patterns/BusinessDetailTemplate.tsx"),
"utf8",
);
const workflowSource = fs.readFileSync(
path.resolve(__dirname, "../../../../client/src/pages/WorkflowTaskDetailPage.tsx"),
"utf8",
);
const cssSource = fs.readFileSync(
path.resolve(__dirname, "../../../../client/src/index.css"),
"utf8",
);
const workflowPanelRule = cssSource.match(/\.workflow-action-panel\s*\{([^}]*)\}/)?.[1] ?? "";
expect(templateSource).toContain("detail-action-panel lg:sticky lg:top-24");
expect(workflowSource).toContain('className="workflow-action-panel"');
expect(workflowSource).not.toMatch(/className="workflow-action-panel[^"]*lg:top-/);
expect(workflowPanelRule).toContain("@apply relative z-30;");
expect(workflowPanelRule).not.toMatch(/lg:(?:sticky|top-)/);
});
});
const fs = require("node:fs");
const path = require("node:path");