Skip to content

Commit 4d2eb40

Browse files
Merge pull request #47 from InstaNode-dev/fix/playwright-ci-gate-fresh
e2e: fix navigation + resources playwright specs (admin-bypass becomes unnecessary)
2 parents db65955 + 4f34856 commit 4d2eb40

3 files changed

Lines changed: 32 additions & 9 deletions

File tree

e2e/fixtures.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,8 +70,11 @@ export async function installAPIFake(page: Page) {
7070
}),
7171
)
7272

73-
// GET /api/v1/resources
74-
await page.route('**/api/v1/resources', (route: Route) => {
73+
// GET /api/v1/resources (optional ?env=... query string — ResourcesPage
74+
// calls listResources(ctx.env) which produces /api/v1/resources?env=production).
75+
// A bare-glob `**/api/v1/resources` only matches the no-query path, so we
76+
// use a regex anchored on the path + optional query string.
77+
await page.route(/\/api\/v1\/resources(\?[^/]*)?$/, (route: Route) => {
7578
if (route.request().method() === 'GET') {
7679
return route.fulfill({
7780
status: 200,

e2e/navigation.spec.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,16 @@ test.describe('Navigation', () => {
1010
test('every nav link reaches its page', async ({ page }) => {
1111
// The authenticated app is mounted under /app/*; the sidebar nav links
1212
// point to /app/<section>. The Overview is just /app (or /app/).
13+
//
14+
// Tracks the live AppShell sidebar — Stacks was retired (b13b8ee:
15+
// "/app/stacks duplicate route + StacksPage.tsx deleted, same data as
16+
// Deployments") and Team has no sidebar nav link in the user-facing
17+
// sidebar (the route exists but is no longer linked from chrome).
1318
await page.goto('/app')
1419
const targets: { name: RegExp; pathFragment?: string }[] = [
1520
{ name: /Resources/i, pathFragment: '/app/resources' },
1621
{ name: /Deployments/i, pathFragment: '/app/deployments' },
17-
{ name: /Stacks/i, pathFragment: '/app/stacks' },
1822
{ name: /Vault/i, pathFragment: '/app/vault' },
19-
{ name: /Team/i, pathFragment: '/app/team' },
2023
{ name: /Billing/i, pathFragment: '/app/billing' },
2124
{ name: /Settings/i, pathFragment: '/app/settings' },
2225
{ name: /Overview/i, pathFragment: '/app' },

src/App.tsx

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { lazy, Suspense } from 'react'
2-
import { BrowserRouter, Navigate, Route, Routes, useLocation } from 'react-router-dom'
2+
import { BrowserRouter, Navigate, Route, Routes, useLocation, useParams } from 'react-router-dom'
33

44
// Homepage — eagerly imported. It's the cold-load path and the most-visited
55
// public surface, so it stays in the main entry chunk.
@@ -115,6 +115,19 @@ function AuthGate({ children }: { children: JSX.Element }) {
115115
return children
116116
}
117117

118+
// LegacyRedirect — <Navigate to="/app/resources/:id"> sends a literal ":id"
119+
// string instead of the captured route param (Navigate is dumb — it doesn't
120+
// interpolate). This wrapper reads the param and constructs the real
121+
// destination so /resources/<token> → /app/resources/<token> works.
122+
function LegacyResourceRedirect() {
123+
const { id = '' } = useParams()
124+
return <Navigate to={`/app/resources/${id}`} replace />
125+
}
126+
function LegacyDeploymentRedirect() {
127+
const { id = '' } = useParams()
128+
return <Navigate to={`/app/deployments/${id}`} replace />
129+
}
130+
118131
// AppLoadingFallback — shown while a lazy-loaded /app/* chunk is in flight.
119132
// Tiny inline style so it renders even before the page's own CSS resolves.
120133
// In practice this fallback is on screen for ~50-150ms on a warm cache.
@@ -209,12 +222,16 @@ export function AppRoutes() {
209222
</Route>
210223

211224
{/* Back-compat: every legacy unprefixed path that used to be a
212-
dashboard route now redirects under /app. */}
225+
dashboard route now redirects under /app. Parameterized routes
226+
use a wrapper that interpolates the captured param — see
227+
LegacyResourceRedirect / LegacyDeploymentRedirect above
228+
(Navigate's `to` is literal, not parameterized). */}
213229
<Route path="/resources" element={<Navigate to="/app/resources" replace />} />
214-
<Route path="/resources/:id" element={<Navigate to="/app/resources/:id" replace />} />
230+
<Route path="/resources/:id" element={<LegacyResourceRedirect />} />
215231
<Route path="/deployments" element={<Navigate to="/app/deployments" replace />} />
216-
<Route path="/deployments/:id" element={<Navigate to="/app/deployments/:id" replace />} />
217-
<Route path="/stacks" element={<Navigate to="/app/stacks" replace />} />
232+
<Route path="/deployments/:id" element={<LegacyDeploymentRedirect />} />
233+
{/* /stacks legacy path retired with the route (b13b8ee). Falls
234+
through to the catch-all → /. */}
218235
<Route path="/vault" element={<Navigate to="/app/vault" replace />} />
219236
<Route path="/team" element={<Navigate to="/app/team" replace />} />
220237
<Route path="/billing" element={<Navigate to="/app/billing" replace />} />

0 commit comments

Comments
 (0)