From 2f868d006a77f1de1ff1fe0d5cfe83429820bd12 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 29 Jul 2026 11:12:13 +0000 Subject: [PATCH 1/5] ci: allow workshops without typecheck script Co-authored-by: Kent C. Dodds --- .github/workflows/validate.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 1f702fa..8cf3809 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -63,7 +63,7 @@ jobs: done - name: ʦ TypeScript - run: npm run typecheck + run: npm run typecheck --if-present working-directory: ./workshop - name: ⬣ Lint From 25ead7d8f69577b6fe66f0473d3a277832d6f453 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 29 Jul 2026 11:38:04 +0000 Subject: [PATCH 2/5] ci: install Playwright with supported Node version Co-authored-by: Kent C. Dodds --- .github/workflows/validate.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 8cf3809..329fe97 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -88,10 +88,23 @@ jobs: - name: 📦 Install dependencies run: npm ci + # Playwright 1.51 hangs while extracting Chromium under Node 26. + - name: ⎔ Use Node 22 for Playwright installation + if: ${{ hashFiles('epicshop/test.js') != '' }} + uses: actions/setup-node@v4 + with: + node-version: 22 + - name: 🎭 Install Playwright browser if: ${{ hashFiles('epicshop/test.js') != '' }} run: npx playwright install --with-deps chromium + - name: ⎔ Restore Node 26 + if: ${{ hashFiles('epicshop/test.js') != '' }} + uses: actions/setup-node@v4 + with: + node-version: 26 + - name: ◭ Generate Prisma clients if: ${{ hashFiles('epicshop/test.js') != '' }} run: | From 3c2740b7af41a3f91872ca578d841b4165311e36 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 29 Jul 2026 11:59:25 +0000 Subject: [PATCH 3/5] ci: run Playwright tests on Node 22 Co-authored-by: Kent C. Dodds --- .github/workflows/validate.yml | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 329fe97..ee661eb 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -83,28 +83,17 @@ jobs: - name: ⎔ Setup node uses: actions/setup-node@v4 with: - node-version: 26 + # Playwright 1.51's browser install and test runner hang under Node 26. + # The setup matrix above still validates the workshop under Node 26. + node-version: 22 - name: 📦 Install dependencies run: npm ci - # Playwright 1.51 hangs while extracting Chromium under Node 26. - - name: ⎔ Use Node 22 for Playwright installation - if: ${{ hashFiles('epicshop/test.js') != '' }} - uses: actions/setup-node@v4 - with: - node-version: 22 - - name: 🎭 Install Playwright browser if: ${{ hashFiles('epicshop/test.js') != '' }} run: npx playwright install --with-deps chromium - - name: ⎔ Restore Node 26 - if: ${{ hashFiles('epicshop/test.js') != '' }} - uses: actions/setup-node@v4 - with: - node-version: 26 - - name: ◭ Generate Prisma clients if: ${{ hashFiles('epicshop/test.js') != '' }} run: | From 52d3dca9fdee6d812528e3552f29d83ffbd4d597 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 29 Jul 2026 12:08:57 +0000 Subject: [PATCH 4/5] test: wait for routable ship link Co-authored-by: Kent C. Dodds --- .../01.solution.router/tests/client-side-routing.test.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/exercises/04.router/01.solution.router/tests/client-side-routing.test.js b/exercises/04.router/01.solution.router/tests/client-side-routing.test.js index 69f3616..864eccb 100644 --- a/exercises/04.router/01.solution.router/tests/client-side-routing.test.js +++ b/exercises/04.router/01.solution.router/tests/client-side-routing.test.js @@ -11,11 +11,9 @@ test('should display the home page and perform client-side routing', async ({ reloadCount++ }) - // Wait for the page to load - await page.waitForSelector('a') - - // Get the first link - const firstLink = await page.locator('a').first() + // Wait for the streamed search results to replace placeholder "#" links. + const firstLink = page.locator('a[href*="shipId="]').first() + await firstLink.waitFor() // Get the href attribute of the first link const href = await firstLink.getAttribute('href') From e4a4306d83942958bfa79611aed9895d2cf64d89 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 29 Jul 2026 12:09:39 +0000 Subject: [PATCH 5/5] test: select pathname-based ship route Co-authored-by: Kent C. Dodds --- .../01.solution.router/tests/client-side-routing.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/exercises/04.router/01.solution.router/tests/client-side-routing.test.js b/exercises/04.router/01.solution.router/tests/client-side-routing.test.js index 864eccb..bc0547e 100644 --- a/exercises/04.router/01.solution.router/tests/client-side-routing.test.js +++ b/exercises/04.router/01.solution.router/tests/client-side-routing.test.js @@ -12,7 +12,7 @@ test('should display the home page and perform client-side routing', async ({ }) // Wait for the streamed search results to replace placeholder "#" links. - const firstLink = page.locator('a[href*="shipId="]').first() + const firstLink = page.locator('a[href^="/"]').first() await firstLink.waitFor() // Get the href attribute of the first link