Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 8 additions & 21 deletions apps/web/src/components/nav/panels/PanelSolutions.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -59,29 +59,16 @@ export function PanelSolutions({ item }: Props) {
atmosphere={ATMOSPHERE}
>
<div className="grid grid-cols-3 gap-3">
{/* Col 1: Capability stacked above Compliance */}
<div className="flex flex-col gap-3">
{/* Cols 1 and 2 share one grid so the two rows of groups line up:
Capability beside By role, one divider across both, then
Compliance beside By industry. Two independent stacks drifted as
soon as the groups had different item counts. */}
<div className="col-span-2 grid grid-cols-2 gap-x-3">
{capability && <GroupColumn group={capability} />}
{compliance && (
<>
<div className="h-px bg-white/[0.05]" />
<GroupColumn group={compliance} />
</>
)}
</div>

{/* Col 2: By Role stacked above By Industry, on the same divider
grammar as Col 1. Col 2 held a single two-item group and ran short
against Col 1's five, so the second group lands where the panel
already had vertical room. */}
<div className="flex flex-col gap-3">
{byRole && <GroupColumn group={byRole} />}
{byIndustry && (
<>
<div className="h-px bg-white/[0.05]" />
<GroupColumn group={byIndustry} />
</>
)}
<div className="col-span-2 my-3 h-px bg-white/[0.05]" />
{compliance && <GroupColumn group={compliance} />}
{byIndustry && <GroupColumn group={byIndustry} />}
</div>

{/* Col 3: FIPS featured tile */}
Expand Down
16 changes: 12 additions & 4 deletions apps/web/tests/e2e/impact-estimator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ test.describe("impact estimator copy link @phase-web-impact-estimator", () => {
test.skip(browserName !== "chromium", "clipboard permissions are only grantable in Chromium");
await context.grantPermissions(["clipboard-read", "clipboard-write"]);
await page.goto(`${ROUTE}?images=60&team=15&remediation=Quarterly&release=Monthly`);
// The slider only reads 60 once the page has hydrated and adopted the URL;
// clicking before that lands on a button with no handler yet.
await expect(page.getByRole("slider", { name: "Production images" })).toHaveValue("60");

const button = page.getByRole("button", { name: "Copy link to results" });
await button.click();
Expand All @@ -69,11 +72,16 @@ test.describe("impact estimator mobile summary @phase-web-impact-estimator", ()
const strip = page.locator('button[aria-label^="Jump to your results"]');
await expect(strip).toHaveAttribute("aria-hidden", "true");

// Park the inputs card just under the header: the sliders are usable and
// the gauge sits below the fold on every phone viewport.
// Scroll so the gauge is only a fifth visible at the bottom edge: the inputs
// card is on screen and the readout is not, on phones and tablets alike. A
// fixed offset from the card top would not do: at 768px the card is short
// enough that the gauge is already mostly visible, and the strip rightly
// stays hidden.
await page.evaluate(() => {
const card = document.querySelector<HTMLElement>('[data-section="ImpactSimulator"] .lg\\:sticky');
if (card) window.scrollTo({ top: card.getBoundingClientRect().top + window.scrollY - 80, behavior: "instant" });
const gauge = document.querySelector<HTMLElement>('[data-section="ImpactSimulator"] svg[role="img"]');
if (!gauge) return;
const r = gauge.getBoundingClientRect();
window.scrollTo({ top: r.top + window.scrollY - window.innerHeight + r.height * 0.2, behavior: "instant" });
});
await expect(strip).toHaveAttribute("aria-hidden", "false");
await expect(strip).toHaveAttribute("aria-label", /High runtime complexity, burden 260, 7,800 hours/);
Expand Down
Loading