diff --git a/ui/app/(prowler)/scans/page.test.tsx b/ui/app/(prowler)/scans/page.test.tsx index 5134caef6b..4a8032e492 100644 --- a/ui/app/(prowler)/scans/page.test.tsx +++ b/ui/app/(prowler)/scans/page.test.tsx @@ -63,11 +63,11 @@ vi.mock("@/components/shadcn/content-layout", () => ({ })); vi.mock("@/components/scans/scans-page-shell", () => ({ ScansPageShell: (props: { - children: unknown; + children: ReactNode; providers: ProviderProps[]; }) => { scansPageShellSpy(props); - return
; + return
{props.children}
; }, })); @@ -123,8 +123,8 @@ describe("scans page rendering", () => { const shellProps = scansPageShellSpy.mock.calls.at(-1)?.[0]; expect(shellProps?.providers).toEqual(providers); - // The table subtree is always wired, regardless of provider connection state. - expect(shellProps?.children).toBeTruthy(); + // The scans table subtree actually renders, regardless of provider state. + expect(await screen.findByRole("table")).toBeInTheDocument(); }, ); diff --git a/ui/components/scans/scans-page-shell.test.tsx b/ui/components/scans/scans-page-shell.test.tsx index 6906207516..3f5db065ea 100644 --- a/ui/components/scans/scans-page-shell.test.tsx +++ b/ui/components/scans/scans-page-shell.test.tsx @@ -575,6 +575,21 @@ describe("ScansPageShell", () => { expect(screen.queryByTestId("onboarding-trigger")).not.toBeInTheDocument(); }); + it("suppresses the view-first-scan tour when a provider is connected but manage scans is missing", () => { + vi.stubEnv("NEXT_PUBLIC_IS_CLOUD_ENV", "false"); + + render( + +
Scans table
+
, + ); + + // Launch Scan is disabled without manage_scans, so the tour must not anchor to it. + expect(screen.queryByTestId("onboarding-trigger")).not.toBeInTheDocument(); + // The table (and therefore imported scans) must still render. + expect(screen.getByText("Scans table")).toBeInTheDocument(); + }); + it("still signals page-ready without a connected provider so the navbar replay fallback works", () => { vi.stubEnv("NEXT_PUBLIC_IS_CLOUD_ENV", "false"); diff --git a/ui/components/scans/scans-page-shell.tsx b/ui/components/scans/scans-page-shell.tsx index 56cf315077..8209957879 100644 --- a/ui/components/scans/scans-page-shell.tsx +++ b/ui/components/scans/scans-page-shell.tsx @@ -108,12 +108,13 @@ export function ScansPageShell({ return (
- {/* Only start the scan tour when a provider is connected: its primary target - (Launch Scan) is disabled otherwise, so a `?onboarding=view-first-scan` - URL or active sequence would anchor to an unusable button. The navbar - replay falls back to the add-provider flow in this state (see page.tsx). */} + {/* Gate on the full launch condition: the tour anchors on Launch Scan, which is + disabled without a connected provider AND manage_scans — starting it would + point at an unusable button. Every start path (?onboarding= URL, active + sequence, navbar replay) funnels through this trigger, so gating here covers + them all. */} {/* Suspense required: OnboardingTrigger reads useSearchParams */} - {hasConnectedProviders && ( + {!launchDisabled && (