From 1e67e873218557f67410d4a498fc348c2b696773 Mon Sep 17 00:00:00 2001 From: gsxdsm Date: Sat, 1 Aug 2026 13:03:34 -0700 Subject: [PATCH] FN-8702: fix Git Manager phone sheet spacing Make Git Manager use the standalone phone layout only below the 768px boundary. - Remove the hidden resize-handle gutter from Git Manager phone sheets - Preserve embedded, tablet, and desktop Git Manager geometry - Add responsive layout smoke fixtures and regression coverage - Document the phone-sheet behavior and add a patch changeset Files changed: .changeset/fn-8702-git-manager-mobile-spacing.md | 7 + docs/dashboard-guide.md | 5 +- .../__tests__/browser-layout-smoke-fixture.test.ts | 23 ++++ .../dashboard/app/components/FloatingWindow.css | 12 ++ packages/dashboard/app/components/ScriptsModal.css | 10 +- .../components/__tests__/GitManagerModal.test.tsx | 31 +++-- packages/dashboard/scripts/browser-layout-smoke.mjs| 143 +++++++++++++++++++++ 7 files changed, 211 insertions(+), 20 deletions(-) Fusion-Task-Id: FN-8702 Fusion-Task-Lineage: 52473a8a-d3a7-48d2-b768-fc2f6fcd18b9 Co-authored-by: Fusion (runfusion.ai) --- .../fn-8702-git-manager-mobile-spacing.md | 7 + docs/dashboard-guide.md | 5 +- .../browser-layout-smoke-fixture.test.ts | 23 +++ .../app/components/FloatingWindow.css | 12 ++ .../dashboard/app/components/ScriptsModal.css | 10 +- .../__tests__/GitManagerModal.test.tsx | 31 ++-- .../scripts/browser-layout-smoke.mjs | 143 ++++++++++++++++++ 7 files changed, 211 insertions(+), 20 deletions(-) create mode 100644 .changeset/fn-8702-git-manager-mobile-spacing.md diff --git a/.changeset/fn-8702-git-manager-mobile-spacing.md b/.changeset/fn-8702-git-manager-mobile-spacing.md new file mode 100644 index 0000000000..ab0592791c --- /dev/null +++ b/.changeset/fn-8702-git-manager-mobile-spacing.md @@ -0,0 +1,7 @@ +--- +"@runfusion/fusion": patch +--- + +summary: Fix Git Manager mobile sheets leaving excess space at the right edge. +category: fix +dev: Resets the resize-handle gutter only below the standalone 768px phone boundary. diff --git a/docs/dashboard-guide.md b/docs/dashboard-guide.md index 55c2d89862..8b2974efb9 100644 --- a/docs/dashboard-guide.md +++ b/docs/dashboard-guide.md @@ -903,7 +903,8 @@ See `docs/solutions/developer-experience/login-shell-profile-latency.md` for the ## Git Manager -Git Manager centralizes repo operations in the dashboard. On desktop/tablet it is available as an embedded right-dock panel and can expand into a resizable modal; on mobile it opens from the compact More surfaces. + +Git Manager centralizes repo operations in the dashboard. On desktop/tablet (including exactly 768px) it is available as an embedded right-dock panel and can expand into a resizable modal; below 768px it opens as a full-width standalone phone sheet from the compact More surfaces. Use Git Manager: @@ -912,7 +913,7 @@ Use Git Manager: 2. Select the dock expand action if you need more room. Expected outcome: the same Git Manager surface opens in a resizable modal without changing the selected dock tool. 3. On mobile, open the compact Header overflow or bottom **More** sheet and select **Git Manager**. - Expected outcome: Git Manager opens in the mobile modal layout with the section tabs restored as a horizontal scrolling strip. + Expected outcome: Git Manager opens as a full-width phone sheet with no desktop resize-handle gutter; its section tabs remain a horizontal scrolling strip. Embedded dock panels never take over the viewport. 4. Select **Status**, **Changes**, **Commits**, **Branches**, **Worktrees**, **Stashes**, **Recovery**, or **Remotes**. Expected outcome: the corresponding section panel replaces the previous section while preserving the same Git Manager session. diff --git a/packages/dashboard/app/__tests__/browser-layout-smoke-fixture.test.ts b/packages/dashboard/app/__tests__/browser-layout-smoke-fixture.test.ts index 0133dbdcc6..68d7da17f0 100644 --- a/packages/dashboard/app/__tests__/browser-layout-smoke-fixture.test.ts +++ b/packages/dashboard/app/__tests__/browser-layout-smoke-fixture.test.ts @@ -2,6 +2,29 @@ import { describe, expect, it } from "vitest"; import { createSmokeHtml } from "../../scripts/browser-layout-smoke.mjs"; describe("browser layout smoke fixture", () => { + it("includes standalone and embedded Git Manager shell fixtures", () => { + const html = createSmokeHtml(); + for (const hook of [ + "git-manager-standalone", + "git-manager-standalone-body", + "git-manager-standalone-modal", + "git-manager-standalone-header", + "git-manager-standalone-close", + "git-manager-standalone-layout", + "git-manager-standalone-content", + "git-manager-embedded-host", + "git-manager-embedded-modal", + "git-manager-embedded-header", + "git-manager-embedded-close", + "git-manager-embedded-layout", + "git-manager-embedded-content", + ]) { + expect(html).toContain(`data-smoke="${hook}"`); + } + expect(html).toContain("floating-window--git-manager"); + expect(html).toContain("gm-modal--embedded"); + }); + it("includes PR flow fixture sections and class hooks", () => { const html = createSmokeHtml(); expect(html).toContain('data-smoke="pr-create-modal"'); diff --git a/packages/dashboard/app/components/FloatingWindow.css b/packages/dashboard/app/components/FloatingWindow.css index 1d54a6f0ce..dffeb46d6e 100644 --- a/packages/dashboard/app/components/FloatingWindow.css +++ b/packages/dashboard/app/components/FloatingWindow.css @@ -490,6 +490,18 @@ all floating affordances so persisted desktop geometry cannot imply a draggable } } +@media (max-width: 767.98px) { + /* + FNXC:GitManagerMobileSpacing 2026-08-01-19:10: + FN-8702 keeps the shared desktop resize-handle clearance for tablet and desktop windows. + A standalone Git Manager phone sheet hides those handles, so only below the strict 768px + boundary its body clears the obsolete inline-end gutter and aligns its header and close control. + */ + .floating-window--git-manager .floating-window__body { + margin-inline-end: 0; + } +} + /* FNXC:FloatingWindow 2026-07-15-18:20: Long titles (e.g. the GitHub import detail's "#2159 — ") must truncate with an ellipsis rather than hard-cut mid-word against the close button. diff --git a/packages/dashboard/app/components/ScriptsModal.css b/packages/dashboard/app/components/ScriptsModal.css index fe3f1810a9..494e414fdb 100644 --- a/packages/dashboard/app/components/ScriptsModal.css +++ b/packages/dashboard/app/components/ScriptsModal.css @@ -2140,7 +2140,7 @@ The embedded host fills its right-dock container; the inner shell drops overlay- FNXC:GitManager 2026-06-22-17:30: The embedded Git Manager adapts to its CONTAINER width, not the viewport, so the SAME embedded render works in both the narrow right dock and the wide pop-out (expand) modal: - Wide container (expand modal, > 560px): inherits the default desktop layout — vertical section sidebar + content (two-pane, like before). Those default rules live OUTSIDE this container query and are untouched. -- Narrow container (dock, <= 560px): MIRRORS the phone-width (@media max-width:768px) gm layout exactly. Section tabs become a horizontal strip with ICON + TEXT LABEL per tab (the mobile .gm-nav-item: column, icon over label, comfortable padding), and every section (status grid, create form, branches, stashes, changes/files split, and the REMOTES view) collapses to its mobile single-column form. The remotes view is CSS-only (no JS width gating in GitManagerModal.tsx), so mirroring the @media remotes rules here gives the dock the mobile remotes selector strip + stacked detail. +- Narrow container (dock, <= 560px): MIRRORS the phone-width (@media max-width:767.98px) gm layout exactly. Section tabs become a horizontal strip with ICON + TEXT LABEL per tab (the mobile .gm-nav-item: column, icon over label, comfortable padding), and every section (status grid, create form, branches, stashes, changes/files split, and the REMOTES view) collapses to its mobile single-column form. The remotes view is CSS-only (no JS width gating in GitManagerModal.tsx), so mirroring the @media remotes rules here gives the dock the mobile remotes selector strip + stacked detail. The previous bespoke rules here hid the tab labels (icon-only) and used a cramped strip; the user wants labeled tabs, more spacing, and the mobile remotes layout, so we now mirror the @media gm INTERNAL rules verbatim under the .gm-modal--embedded prefix. Only the viewport-takeover (.modal.gm-modal 100vw/100dvh) rules are NOT mirrored — they are scoped to :not(.gm-modal--embedded) and must never apply to the embedded pane. */ @container gm-embedded (max-width: 560px) { @@ -4364,7 +4364,7 @@ Worktree commit-history jumps are read-only navigation affordances. Keep the act /* ── Responsive ── */ -@media (max-width: 768px) { +@media (max-width: 767.98px) { .gm-changes-split { grid-template-columns: 1fr; } @@ -4453,7 +4453,7 @@ Worktree commit-history jumps are read-only navigation affordances. Keep the act } } -@media (max-width: 768px) { +@media (max-width: 767.98px) { /* Full-screen sheet on mobile — drop overlay padding so the modal actually fills the viewport instead of being pushed below it. FNXC:GitManager 2026-06-22-16:00: scope the viewport-takeover to the @@ -4547,7 +4547,7 @@ Worktree commit-history jumps are read-only navigation affordances. Keep the act /* FNXC:GitManager 2026-06-22-19:35: - Mobile (<=768px) nav strip: ICON-ONLY compact tabs in one horizontally-scrolling row so multiple sections are visible at once. width:auto overrides the base .gm-nav-item width:100% that otherwise made each tab fill the row (one tab, swipe-only). Labels are sr-only (button title is the tooltip). + Phone (<768px) nav strip: ICON-ONLY compact tabs in one horizontally-scrolling row so multiple sections are visible at once. width:auto overrides the base .gm-nav-item width:100% that otherwise made each tab fill the row (one tab, swipe-only). Labels are sr-only (button title is the tooltip). */ .gm-nav-item { flex: 0 0 auto; @@ -5063,7 +5063,7 @@ Worktree commit-history jumps are read-only navigation affordances. Keep the act color: var(--text); } -@media (max-width: 768px) { +@media (max-width: 767.98px) { /* Git manager: extend the canonical mobile rules above with safe-area and panel scroll behavior only. */ .gm-content { padding-bottom: max(var(--space-md), env(safe-area-inset-bottom, 0px)); diff --git a/packages/dashboard/app/components/__tests__/GitManagerModal.test.tsx b/packages/dashboard/app/components/__tests__/GitManagerModal.test.tsx index ad866094a7..53f02e7642 100644 --- a/packages/dashboard/app/components/__tests__/GitManagerModal.test.tsx +++ b/packages/dashboard/app/components/__tests__/GitManagerModal.test.tsx @@ -3712,6 +3712,11 @@ describe("GitManagerModal", () => { }); describe("CSS regression coverage", () => { + /* + FNXC:GitManagerMobileSpacing 2026-08-01-19:10: + FN-8702 makes Git Manager's standalone sheet rules strictly phone-only. These source + assertions protect the 767.98px selector boundary while Chromium verifies the resulting geometry. + */ it("includes remotes layout selectors and mobile rules", () => { const css = loadAllAppCss(); expect(css).toContain(".gm-remotes-layout"); @@ -3719,7 +3724,7 @@ describe("GitManagerModal", () => { expect(css).toContain(".gm-remote-detail"); expect(css).toContain(".gm-remote-sync-card"); expect(css).toContain(".gm-remote-detail-card"); - expect(css).toMatch(/@media[^{]*\(max-width: 768px\)[^{]*\{[\s\S]*?\.gm-remotes-layout[\s\S]*?\.gm-remote-selector[\s\S]*?\}/); + expect(css).toMatch(/@media[^{]*\(max-width: 767\.98px\)[^{]*\{[\s\S]*?\.gm-remotes-layout[\s\S]*?\.gm-remote-selector[\s\S]*?\}/); }); it("keeps remotes-specific status/surface styles tokenized", () => { @@ -3733,24 +3738,24 @@ describe("GitManagerModal", () => { it("includes mobile wrapping rules for changes file rows and section actions", () => { const css = loadAllAppCss(); - expect(css).toMatch(/@media[^{]*\(max-width: 768px\)[^{]*\{[\s\S]*?\.gm-file-section-actions\s*\{[\s\S]*?flex-wrap:\s*wrap;[\s\S]*?flex:\s*1 1 100%;/); - expect(css).toMatch(/@media[^{]*\(max-width: 768px\)[^{]*\{[\s\S]*?\.gm-file-item\s*\{[\s\S]*?min-width:\s*0;[\s\S]*?flex-wrap:\s*wrap;/); - expect(css).toMatch(/@media[^{]*\(max-width: 768px\)[^{]*\{[\s\S]*?\.gm-file-section\s*\{[\s\S]*?max-width:\s*100%;/); + expect(css).toMatch(/@media[^{]*\(max-width: 767\.98px\)[^{]*\{[\s\S]*?\.gm-file-section-actions\s*\{[\s\S]*?flex-wrap:\s*wrap;[\s\S]*?flex:\s*1 1 100%;/); + expect(css).toMatch(/@media[^{]*\(max-width: 767\.98px\)[^{]*\{[\s\S]*?\.gm-file-item\s*\{[\s\S]*?min-width:\s*0;[\s\S]*?flex-wrap:\s*wrap;/); + expect(css).toMatch(/@media[^{]*\(max-width: 767\.98px\)[^{]*\{[\s\S]*?\.gm-file-section\s*\{[\s\S]*?max-width:\s*100%;/); }); it("includes commit target and worktree actions in modal mobile and embedded narrow layouts", () => { const css = loadAllAppCss(); - const mobile768 = getMediaBlocks(css, /@media[^{]*\(max-width:\s*768px\)[^{]*\{/g).join("\n"); + const phone767 = getMediaBlocks(css, /@media[^{]*\(max-width:\s*767\.98px\)[^{]*\{/g).join("\n"); const embeddedNarrow = getMediaBlocks(css, /@container\s+gm-embedded\s+\(max-width:\s*560px\)\s*\{/g).join("\n"); expect(css).toContain(".gm-commit-target"); expect(css).toContain(".gm-worktree-actions"); - expect(mobile768).toContain(".gm-commit-target select"); - expect(mobile768).toContain(".gm-worktree-actions .btn"); + expect(phone767).toContain(".gm-commit-target select"); + expect(phone767).toContain(".gm-worktree-actions .btn"); expect(embeddedNarrow).toContain(".gm-modal--embedded .gm-commit-target select"); expect(embeddedNarrow).toContain(".gm-modal--embedded .gm-worktree-actions .btn"); - const mobileTargetRules = getRuleBlocks(mobile768, ".gm-commit-target,\n .gm-commit-target select,\n .gm-commit-controls .gm-search-box"); + const mobileTargetRules = getRuleBlocks(phone767, ".gm-commit-target,\n .gm-commit-target select,\n .gm-commit-controls .gm-search-box"); expect(mobileTargetRules).toHaveLength(1); expect(mobileTargetRules[0]).toContain("width: 100%;"); const embeddedTargetRules = getRuleBlocks(embeddedNarrow, ".gm-modal--embedded .gm-commit-target,\n .gm-modal--embedded .gm-commit-target select,\n .gm-modal--embedded .gm-commit-controls .gm-search-box"); @@ -3758,12 +3763,12 @@ describe("GitManagerModal", () => { expect(embeddedTargetRules[0]).toContain("width: 100%;"); }); - it("keeps the mobile Git Manager tab strip non-shrinking at 768px and 720px breakpoints", () => { + it("keeps the mobile Git Manager tab strip non-shrinking below 768px and at 720px", () => { const css = loadAllAppCss(); - const mobile768 = getMediaBlocks(css, /@media[^{]*\(max-width:\s*768px\)[^{]*\{/g).join("\n"); + const phone767 = getMediaBlocks(css, /@media[^{]*\(max-width:\s*767\.98px\)[^{]*\{/g).join("\n"); const mobile720 = getMediaBlocks(css, /@media[^{]*\(max-width:\s*720px\)[^{]*\{/g).join("\n"); - const sidebarRules = getRuleBlocks(mobile768, ".gm-sidebar"); + const sidebarRules = getRuleBlocks(phone767, ".gm-sidebar"); expect(sidebarRules).toHaveLength(1); expect(sidebarRules[0]).toContain("flex: 0 0 auto;"); expect(sidebarRules[0]).toContain("min-height: calc(var(--space-2xl) + var(--space-md));"); @@ -3774,13 +3779,13 @@ describe("GitManagerModal", () => { expect(sidebarRules[0]).toContain("-webkit-overflow-scrolling: touch;"); expect(sidebarRules[0]).toContain("overscroll-behavior-x: contain;"); - const navItemRules = getRuleBlocks(mobile768, ".gm-nav-item"); + const navItemRules = getRuleBlocks(phone767, ".gm-nav-item"); expect(navItemRules).toHaveLength(1); // Mobile tabs are compact ICON-ONLY in one scrolling row: non-shrinking via flex:0 0 auto + intrinsic width:auto (overrides the base .gm-nav-item width:100% that otherwise made one tab fill the row). expect(navItemRules[0]).toContain("flex: 0 0 auto;"); expect(navItemRules[0]).toContain("width: auto;"); - const refreshRules = getRuleBlocks(mobile768, ".gm-nav-refresh"); + const refreshRules = getRuleBlocks(phone767, ".gm-nav-refresh"); expect(refreshRules).toHaveLength(1); expect(refreshRules[0]).toContain("flex: 0 0 auto;"); expect(refreshRules[0]).toContain("width: auto;"); diff --git a/packages/dashboard/scripts/browser-layout-smoke.mjs b/packages/dashboard/scripts/browser-layout-smoke.mjs index 0d4912f5c9..433b56c593 100644 --- a/packages/dashboard/scripts/browser-layout-smoke.mjs +++ b/packages/dashboard/scripts/browser-layout-smoke.mjs @@ -19,6 +19,8 @@ const requireBrowser = process.argv.includes("--require-browser") || process.env const screenshotPath = process.env.FUSION_BROWSER_SMOKE_SCREENSHOT; const agentHeartbeatMobileScreenshotPath = process.env.FUSION_AGENT_HEARTBEAT_MOBILE_SCREENSHOT; const agentHeartbeatDesktopScreenshotPath = process.env.FUSION_AGENT_HEARTBEAT_DESKTOP_SCREENSHOT; +const gitManagerBeforeMobileScreenshotPath = process.env.FUSION_GIT_MANAGER_BEFORE_MOBILE_SCREENSHOT; +const gitManagerAfterMobileScreenshotPath = process.env.FUSION_GIT_MANAGER_AFTER_MOBILE_SCREENSHOT; function log(message) { console.log(`[dashboard-browser-smoke] ${message}`); @@ -230,6 +232,29 @@ export function createSmokeHtml() { `).join(""); + /* + FNXC:GitManagerMobileSpacing 2026-08-01-19:10: + FN-8702 measures the emitted standalone FloatingWindow chain and the embedded container separately. + The phone-only gutter reset must align every standalone shell edge below 768px without turning the + embedded pane or the 768px-and-up movable window into a viewport sheet. + */ + const gitManagerFixtures = ` +
+
+ +
+ +
+
+ +
`; + return ` @@ -240,6 +265,7 @@ export function createSmokeHtml() {
+ ${gitManagerFixtures}
@@ -1143,6 +1169,123 @@ async function runSmokeChecks(page, pageUrl) { JSON.stringify(modalLayout), ); + /* + FNXC:GitManagerMobileSpacing 2026-08-01-19:10: + Real Chromium must prove the original 390px body-gutter failure is gone across the header, + close control, layout, and populated/error content. The strict 767.98px boundary intentionally + does not claim a false 768px containment failure: production flex shrinking contains that child, + while its desktop/tablet gutter and movable geometry must remain present. + */ + for (const width of [390, 767, 768, 1024]) { + await page.send("Emulation.setDeviceMetricsOverride", { + width, + height: 844, + deviceScaleFactor: width < 768 ? 2 : 1, + mobile: width < 768, + }); + await evaluate(page, "document.fonts ? document.fonts.ready.then(() => true) : true"); + const gitManagerLayout = await evaluate(page, `(() => { + const viewportWidth = window.innerWidth; + const readRect = (selector) => { + const rect = document.querySelector(selector).getBoundingClientRect(); + return { left: rect.left, right: rect.right, width: rect.width, top: rect.top, bottom: rect.bottom }; + }; + const standalone = document.querySelector('[data-smoke="git-manager-standalone"]'); + const standaloneBody = document.querySelector('[data-smoke="git-manager-standalone-body"]'); + const embeddedHost = document.querySelector('[data-smoke="git-manager-embedded-host"]'); + return { + viewportWidth, + documentOverflow: document.documentElement.scrollWidth - viewportWidth, + standalone: { + host: readRect('[data-smoke="git-manager-standalone"]'), + body: readRect('[data-smoke="git-manager-standalone-body"]'), + modal: readRect('[data-smoke="git-manager-standalone-modal"]'), + header: readRect('[data-smoke="git-manager-standalone-header"]'), + close: readRect('[data-smoke="git-manager-standalone-close"]'), + layout: readRect('[data-smoke="git-manager-standalone-layout"]'), + content: readRect('[data-smoke="git-manager-standalone-content"]'), + bodyMarginInlineEnd: getComputedStyle(standaloneBody).marginInlineEnd, + overflow: standalone.scrollWidth - standalone.clientWidth, + resizeHandleDisplay: getComputedStyle(standalone.querySelector('.floating-window__resize-handle')).display, + }, + embedded: { + host: readRect('[data-smoke="git-manager-embedded-host"]'), + modal: readRect('[data-smoke="git-manager-embedded-modal"]'), + header: readRect('[data-smoke="git-manager-embedded-header"]'), + close: readRect('[data-smoke="git-manager-embedded-close"]'), + layout: readRect('[data-smoke="git-manager-embedded-layout"]'), + content: readRect('[data-smoke="git-manager-embedded-content"]'), + overflow: embeddedHost.scrollWidth - embeddedHost.clientWidth, + }, + }; + })()`); + if (width === 390 && gitManagerBeforeMobileScreenshotPath) { + /* + FNXC:GitManagerMobileSpacing 2026-08-01-19:31: + FN-8702 preserves an executable reproduction by temporarily restoring the inherited desktop + resize-handle gutter. Chromium must observe that resulting right-edge asymmetry before the + production phone-sheet assertion proves the reset removes it. + */ + const preFixLayout = await evaluate(page, `(() => { + const body = document.querySelector('[data-smoke="git-manager-standalone-body"]'); + body.style.marginInlineEnd = 'var(--space-lg)'; + const rect = body.getBoundingClientRect(); + return { right: rect.right, marginInlineEnd: getComputedStyle(body).marginInlineEnd, viewportWidth: window.innerWidth }; + })()`); + assertSmokeResult( + "Git Manager 390px desktop-gutter reproduction", + parseFloat(preFixLayout.marginInlineEnd) > 0 && preFixLayout.right < preFixLayout.viewportWidth - 1, + JSON.stringify(preFixLayout), + ); + const screenshot = await page.send("Page.captureScreenshot", { format: "png" }); + await writeFile(gitManagerBeforeMobileScreenshotPath, Buffer.from(screenshot.data, "base64")); + await evaluate(page, "document.querySelector('[data-smoke=\"git-manager-standalone-body\"]').style.removeProperty('margin-inline-end')"); + log(`saved Git Manager before mobile screenshot to ${gitManagerBeforeMobileScreenshotPath}`); + } + if (width === 390 && gitManagerAfterMobileScreenshotPath) { + const screenshot = await page.send("Page.captureScreenshot", { format: "png" }); + await writeFile(gitManagerAfterMobileScreenshotPath, Buffer.from(screenshot.data, "base64")); + log(`saved Git Manager after mobile screenshot to ${gitManagerAfterMobileScreenshotPath}`); + } + + const standaloneRects = Object.values(gitManagerLayout.standalone) + .filter((value) => value && typeof value === "object" && "left" in value); + const embeddedRects = Object.values(gitManagerLayout.embedded) + .filter((value) => value && typeof value === "object" && "left" in value); + const embeddedContained = embeddedRects.every((rect) => rect.left >= gitManagerLayout.embedded.host.left - 1 + && rect.right <= gitManagerLayout.embedded.host.right + 1); + const standaloneContained = standaloneRects.every((rect) => rect.left >= -1 && rect.right <= width + 1); + const common = gitManagerLayout.documentOverflow <= 1 + && gitManagerLayout.standalone.overflow <= 1 + && gitManagerLayout.embedded.overflow <= 1 + && standaloneContained + && embeddedContained + && gitManagerLayout.standalone.close.right <= gitManagerLayout.standalone.header.right + 1 + && gitManagerLayout.embedded.close.right <= gitManagerLayout.embedded.header.right + 1; + const passed = width < 768 + ? common + && Math.abs(gitManagerLayout.standalone.host.left) <= 1 + && Math.abs(gitManagerLayout.standalone.host.right - width) <= 1 + && Math.abs(gitManagerLayout.standalone.body.right - width) <= 1 + && Math.abs(gitManagerLayout.standalone.modal.right - width) <= 1 + && gitManagerLayout.standalone.bodyMarginInlineEnd === "0px" + && gitManagerLayout.embedded.modal.width < width + : common + && gitManagerLayout.standalone.host.width < width - 1 + && parseFloat(gitManagerLayout.standalone.bodyMarginInlineEnd) > 0 + && gitManagerLayout.standalone.resizeHandleDisplay !== "none" + && gitManagerLayout.embedded.modal.width < width; + assertSmokeResult(`Git Manager standalone and embedded geometry at ${width}px`, passed, JSON.stringify(gitManagerLayout)); + } + + await page.send("Emulation.setDeviceMetricsOverride", { + width: 390, + height: 844, + deviceScaleFactor: 2, + mobile: true, + }); + await evaluate(page, "document.fonts ? document.fonts.ready.then(() => true) : true"); + const prCreateModalLayout = await evaluate(page, `(() => { document.querySelector('[data-smoke="show-pr-create"]').click(); const modal = document.querySelector('[data-smoke="pr-create-modal"] .modal.modal-lg');