Skip to content

Commit 20a8118

Browse files
fix(glass-office): harden models catalog truth
1 parent 21fdbcd commit 20a8118

4 files changed

Lines changed: 543 additions & 122 deletions

File tree

apps/mission-control/e2e/p5-models-slice.spec.ts

Lines changed: 87 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ function activeTeamSection(page: import("./testHarness").Page) {
77
.locator(".mc-page-section-tabs button.mc-page-section-btn-active");
88
}
99

10+
async function dismissVisibleToasts(page: import("./testHarness").Page) {
11+
const dismiss = page.locator(".mc-toast-dismiss");
12+
while ((await dismiss.count()) > 0) {
13+
await dismiss.first().click();
14+
}
15+
}
16+
1017
/**
1118
* P5 Basement · Models & Providers room slice: the Staff and Models rooms
1219
* share the team route but keep distinct stable identities — Staff lands on
@@ -140,10 +147,6 @@ test("@core @p5-models staff/models room identity, the models surface, pin-to-of
140147
await expect(page.locator(".mc-pin-to-office-note.is-error")).toHaveText(
141148
"Pinning this would exceed the six-column, four-row Office canvas.",
142149
);
143-
await page.screenshot({
144-
path: "../../runtime/qa/p5-models-slice/models-full-canvas-refusal.png",
145-
fullPage: true,
146-
});
147150
expect(
148151
await page.evaluate(() => localStorage.getItem("mc-glass-config-v1")),
149152
).toBe(fullCanvasConfig);
@@ -157,6 +160,11 @@ test("@core @p5-models staff/models room identity, the models surface, pin-to-of
157160
);
158161
}),
159162
).toBe(false);
163+
await dismissVisibleToasts(page);
164+
await page.screenshot({
165+
path: "../../runtime/qa/p5-models-slice/models-full-canvas-refusal.png",
166+
fullPage: true,
167+
});
160168

161169
// Free one medium default block. Pin now succeeds, and a repeat pin is
162170
// byte-identical config plus the honest already-pinned note.
@@ -187,6 +195,7 @@ test("@core @p5-models staff/models room identity, the models surface, pin-to-of
187195
expect(
188196
await page.evaluate(() => localStorage.getItem("mc-glass-config-v1")),
189197
).toBe(pinnedConfig);
198+
await dismissVisibleToasts(page);
190199
await page.screenshot({
191200
path: "../../runtime/qa/p5-models-slice/models-pinned-desktop.png",
192201
fullPage: true,
@@ -198,8 +207,10 @@ test("@core @p5-models staff/models room identity, the models surface, pin-to-of
198207
await expect(shortcut).toBeVisible();
199208
await expect(shortcut).toContainText("The Basement");
200209
await shortcut.scrollIntoViewIfNeeded();
201-
await shortcut.screenshot({
210+
await dismissVisibleToasts(page);
211+
await page.screenshot({
202212
path: "../../runtime/qa/p5-models-slice/office-shortcut-block.png",
213+
fullPage: true,
203214
});
204215

205216
// The mounted Office consumes config events live; no route remount may be
@@ -284,6 +295,7 @@ test("@core @p5-models staff/models room identity, the models surface, pin-to-of
284295
await expect(
285296
page.getByTestId("office-block-models").getByRole("status"),
286297
).toHaveText("Unavailable — turn on in Config");
298+
await dismissVisibleToasts(page);
287299
await page.screenshot({
288300
path: "../../runtime/qa/p5-models-slice/models-disabled-door.png",
289301
fullPage: true,
@@ -308,6 +320,7 @@ test("@core @p5-models staff/models room identity, the models surface, pin-to-of
308320
.getByTestId("office-block-models")
309321
.getByRole("button", { name: "Open Models & Providers" }),
310322
).toBeVisible();
323+
await dismissVisibleToasts(page);
311324
await page.screenshot({
312325
path: "../../runtime/qa/p5-models-slice/models-restored-door.png",
313326
fullPage: true,
@@ -322,10 +335,14 @@ test("@core @p5-models staff/models room identity, the models surface, pin-to-of
322335
'button[title="BF · Models & Providers"]',
323336
);
324337
await expect(mobileModelsRoom).toHaveClass(/mc-nav-item-active/);
325-
await expect(mobileModelsRoom.locator(".mc-nav-room-mark")).toHaveText("MP");
326-
await expect(
327-
page.locator('button[title="2F · Staff Directory"] .mc-nav-room-mark'),
328-
).toHaveText("SD");
338+
const mobileModelsMark = mobileModelsRoom.locator(".mc-nav-room-mark");
339+
const mobileStaffMark = page.locator(
340+
'button[title="2F · Staff Directory"] .mc-nav-room-mark',
341+
);
342+
await expect(mobileModelsMark).toBeVisible();
343+
await expect(mobileModelsMark).toHaveText("MP");
344+
await expect(mobileStaffMark).toBeVisible();
345+
await expect(mobileStaffMark).toHaveText("SD");
329346
const marksInViewport = await page.evaluate(() => {
330347
const titles = ["BF · Models & Providers", "2F · Staff Directory"];
331348
return titles.map((title) => {
@@ -334,7 +351,12 @@ test("@core @p5-models staff/models room identity, the models surface, pin-to-of
334351
);
335352
if (!mark) return false;
336353
const rect = mark.getBoundingClientRect();
354+
const style = window.getComputedStyle(mark);
337355
return (
356+
rect.width > 0 &&
357+
rect.height > 0 &&
358+
style.display !== "none" &&
359+
style.visibility !== "hidden" &&
338360
rect.left >= 0 &&
339361
rect.right <= window.innerWidth &&
340362
rect.top >= 0 &&
@@ -343,15 +365,41 @@ test("@core @p5-models staff/models room identity, the models surface, pin-to-of
343365
});
344366
});
345367
expect(marksInViewport).toEqual([true, true]);
368+
const mobileTabs = page
369+
.getByTestId("team-page")
370+
.locator(".mc-page-section-tabs button");
371+
await expect(mobileTabs).toHaveCount(3);
372+
await expect(mobileTabs).toHaveText([
373+
"Agents",
374+
"People & Routing",
375+
"Models & Providers",
376+
]);
377+
for (const tab of await mobileTabs.all()) {
378+
await expect(tab).toBeVisible();
379+
}
346380
const tabsContained = await page.evaluate(() => {
347381
const bar = document.querySelector(
348382
'[data-testid="team-page"] .mc-page-section-tabs',
349383
);
350384
if (!bar) return null;
351385
const barRect = bar.getBoundingClientRect();
386+
const barStyle = window.getComputedStyle(bar);
387+
if (
388+
barRect.width <= 0 ||
389+
barRect.height <= 0 ||
390+
barStyle.display === "none" ||
391+
barStyle.visibility === "hidden"
392+
) {
393+
return null;
394+
}
352395
return Array.from(bar.querySelectorAll("button")).map((button) => {
353396
const rect = button.getBoundingClientRect();
397+
const style = window.getComputedStyle(button);
354398
return (
399+
rect.width > 0 &&
400+
rect.height > 0 &&
401+
style.display !== "none" &&
402+
style.visibility !== "hidden" &&
355403
rect.left >= barRect.left - 1 &&
356404
rect.right <= barRect.right + 1 &&
357405
rect.top >= barRect.top - 1 &&
@@ -368,10 +416,40 @@ test("@core @p5-models staff/models room identity, the models surface, pin-to-of
368416
() => document.documentElement.scrollWidth > window.innerWidth,
369417
);
370418
expect(overflows).toBe(false);
419+
await dismissVisibleToasts(page);
371420
await page.screenshot({
372421
path: "../../runtime/qa/p5-models-slice/models-390.png",
373422
fullPage: true,
374423
});
375424

425+
// The provider grid must also shrink below its former 300px hard minimum
426+
// when shell chrome leaves a narrower nested content area.
427+
await page.setViewportSize({ width: 320, height: 844 });
428+
const providerCardsContained = await page.evaluate(() => {
429+
const grid = document.querySelector(".mc-models-provider-grid");
430+
if (!grid) return null;
431+
const gridRect = grid.getBoundingClientRect();
432+
const cards = Array.from(
433+
grid.querySelectorAll(".mc-models-provider-card"),
434+
);
435+
if (gridRect.width <= 0 || cards.length === 0) return null;
436+
return cards.map((card) => {
437+
const rect = card.getBoundingClientRect();
438+
return (
439+
rect.width > 0 &&
440+
rect.height > 0 &&
441+
rect.left >= gridRect.left - 1 &&
442+
rect.right <= gridRect.right + 1
443+
);
444+
});
445+
});
446+
expect(providerCardsContained).not.toBeNull();
447+
expect(providerCardsContained).not.toContain(false);
448+
expect(
449+
await page.evaluate(
450+
() => document.documentElement.scrollWidth > window.innerWidth,
451+
),
452+
).toBe(false);
453+
376454
expect(browserErrors).toEqual([]);
377455
});

0 commit comments

Comments
 (0)