refactor: establish standalone application boundary

This commit is contained in:
leefer
2026-08-03 21:42:25 +08:00
parent 656f28a96d
commit d6def3af15
322 changed files with 73872 additions and 44656 deletions
+30 -8
View File
@@ -47,6 +47,27 @@ function session(role = "admin", subscribed = true) {
};
}
function waitForApplicationRuntime(page) {
return expect(page.locator("body")).toHaveAttribute("data-runtime-ready", "true");
}
function installApplicationNavigation(page) {
if (page.__xiaobaiNavigationWrapped) return;
page.__xiaobaiNavigationWrapped = true;
const goto = page.goto.bind(page);
const reload = page.reload.bind(page);
page.goto = async (...args) => {
const response = await goto(...args);
await waitForApplicationRuntime(page);
return response;
};
page.reload = async (...args) => {
const response = await reload(...args);
await waitForApplicationRuntime(page);
return response;
};
}
function mentorDirectory(role = "admin") {
const mentors = [
{
@@ -107,6 +128,7 @@ function mentorDirectory(role = "admin") {
}
async function mockApplication(page, authSession = session(), options = {}) {
installApplicationNavigation(page);
let screenerTracking = {
batches: [{
run_id: 44,
@@ -582,8 +604,8 @@ test("night mode covers the application shell and persists across reloads", asyn
const color = (selector) => getComputedStyle(document.querySelector(selector)).backgroundColor;
return {
body: color("body"),
sidebar: color(".sidebar"),
topbar: color(".topbar"),
sidebar: color(".module-nav"),
topbar: color(".app-header"),
tableHead: color("#limitTable thead th"),
};
});
@@ -1850,7 +1872,7 @@ test("mobile shell stays within the viewport", async ({ page }) => {
await expect(page.locator("#globalSearchButton")).toBeVisible();
await expect(page.locator('[data-view="limitPool"]')).toHaveClass(/mobile-active/);
const mobileShell = await page.evaluate(() => {
const header = document.querySelector(".topbar").getBoundingClientRect();
const header = document.querySelector(".app-header").getBoundingClientRect();
const main = document.querySelector(".app-main").getBoundingClientRect();
return { headerBottom: header.bottom, mainTop: main.top };
});
@@ -1949,7 +1971,7 @@ test("new review workflows render account-scoped records", async ({ page }) => {
return { labelHeight: Math.round(labelBox.height), gap: Math.round(textareaBox.top - labelBox.bottom) };
});
expect(journalSpacing).toEqual({ labelHeight: 18, gap: 6 });
await page.screenshot({ path: "test-results/review-stage17-1440.png", fullPage: true });
await page.screenshot({ path: "runtime/test-results/review-stage17-1440.png", fullPage: true });
await page.locator("#openWatchlistDialog").click();
await expect(page.locator("#watchlistDialog")).toBeVisible();
await page.locator("#watchlistSearchInput").fill("002141");
@@ -2169,7 +2191,7 @@ test("screener redesign preserves three clear workspaces across desktop and mobi
const box = await metric.boundingBox();
expect(box.height).toBeLessThanOrEqual(40);
}
await page.screenshot({ path: "test-results/screener-stage15-phase-1440.png", fullPage: true });
await page.screenshot({ path: "runtime/test-results/screener-stage15-phase-1440.png", fullPage: true });
await page.evaluate(() => {
state.screenerSetup.strategies.push({
@@ -2200,7 +2222,7 @@ test("screener redesign preserves three clear workspaces across desktop and mobi
expect(Math.abs(detailBox.y - libraryBox.y)).toBeLessThanOrEqual(1);
expect(libraryBox.width).toBeLessThan(detailBox.width);
await expect(page.locator("#curatedHealthMetrics > div")).toHaveCount(4);
await page.screenshot({ path: "test-results/screener-stage15-strategy-1440.png", fullPage: true });
await page.screenshot({ path: "runtime/test-results/screener-stage15-strategy-1440.png", fullPage: true });
await page.locator('[data-screener-mode="quant"]').click();
await expect(page.locator("#quantScoreRows .quant-score-row")).toHaveCount(5);
@@ -2219,7 +2241,7 @@ test("screener redesign preserves three clear workspaces across desktop and mobi
expect(quantRunBox.width).toBeLessThan(180);
expect((await page.locator("#quantFilterRows .quant-filter-row select").first().boundingBox()).width).toBeLessThanOrEqual(225);
await expect(page.locator('[data-screener-results-slot="quant"] > .screener-results-view')).toBeVisible();
await page.screenshot({ path: "test-results/screener-stage15-quant-1440.png", fullPage: true });
await page.screenshot({ path: "runtime/test-results/screener-stage15-quant-1440.png", fullPage: true });
await page.setViewportSize({ width: 375, height: 812 });
const overflow = await page.evaluate(() => document.documentElement.scrollWidth - window.innerWidth);
@@ -2382,7 +2404,7 @@ test("screener tracking is an internal page populated only by manual candidate a
await expect(page.locator('[data-view="screenerView"]').first()).toHaveClass(/active/);
await expect(page.locator("#trackingTableBody tr")).toHaveCount(2);
await expect(page.locator('[data-view="screenerTrackingView"]')).toHaveCount(0);
await page.screenshot({ path: "test-results/screener-stage15-tracking-1440.png", fullPage: true });
await page.screenshot({ path: "runtime/test-results/screener-stage15-tracking-1440.png", fullPage: true });
page.once("dialog", (dialog) => dialog.accept());
await page.locator('[data-remove-tracking="10"]').click();