From ff637c17bb8b24c467336d768775a2e5b3f1d64c Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Sat, 2 Nov 2024 15:06:23 +0100 Subject: [PATCH 01/22] test: add e2e to pipeline --- .github/workflows/test.yml | 52 +++++++++++++++++++--------- e2e/examples.test.ts | 71 ++++++++++++++++++++++++++++++++++++++ package.json | 3 +- 3 files changed, 109 insertions(+), 17 deletions(-) create mode 100644 e2e/examples.test.ts diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a5409e4c..ade53dac 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -7,7 +7,7 @@ on: branches: [canary] jobs: - bun-tests: + setup: runs-on: ${{ matrix.os }} if: ${{ !contains(github.event.head_commit.message, 'docs:') }} strategy: @@ -15,6 +15,7 @@ jobs: os: [ubuntu-latest, windows-latest, macos-latest] steps: - uses: actions/checkout@v4 + - name: Setup Node.js uses: actions/setup-node@v3 with: @@ -23,32 +24,51 @@ jobs: uses: oven-sh/setup-bun@v1 with: bun-version: 1.1.35 + + - name: Cache Bun dependencies + uses: actions/cache@v3 + with: + path: ~/.bun/install/cache/v1 + key: ${{ runner.os }}-bun-${{ hashFiles('**/package.json') }} + restore-keys: | + ${{ runner.os }}-bun- + - name: Install dependencies run: bun install + - name: Build project - run: bun run build && bun run create-brisa:build + run: | + bun run build + bun run create-brisa:build + + bun-tests: + needs: setup + runs-on: ${{ matrix.os }} + if: ${{ !contains(github.event.head_commit.message, 'docs:') }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + steps: - name: Run Bun tests - run: bun test + run: bun run test + + e2e-tests: + needs: setup + runs-on: ${{ matrix.os }} + strategy: + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + steps: + - name: Run e2e tests + run: bun run test:e2e node-tests: + needs: setup runs-on: ${{ matrix.os }} if: ${{ !contains(github.event.head_commit.message, 'docs:') }} strategy: matrix: os: [ubuntu-latest, windows-latest, macos-latest] steps: - - uses: actions/checkout@v4 - - name: Setup Node.js - uses: actions/setup-node@v3 - with: - node-version: "22" - - name: Setup Bun.js - uses: oven-sh/setup-bun@v1 - with: - bun-version: 1.1.35 - - name: Install dependencies - run: bun install - - name: Build project - run: bun run build && bun run create-brisa:build - name: Run Node.js tests run: bun run test:node diff --git a/e2e/examples.test.ts b/e2e/examples.test.ts new file mode 100644 index 00000000..bc00d8ca --- /dev/null +++ b/e2e/examples.test.ts @@ -0,0 +1,71 @@ +import { describe, it , expect } from 'bun:test' +import fs from 'node:fs' +import path from 'node:path' + +describe('e2e examples', () => { + describe('with-api-routes', () => { + it('todo', () => { + expect(true).toBeTrue() + }) + }) + + describe('with-elysia', () => { + it('todo', () => { + expect(true).toBeTrue() + }) + }) + + describe('with-external-web-component', () => { + it('todo', () => { + expect(true).toBeTrue() + }) + }) + + describe('with-i18n', () => { + it('todo', () => { + expect(true).toBeTrue() + }) + }) + + describe('with-middleware', () => { + it('todo', () => { + expect(true).toBeTrue() + }) + }) + + describe('with-pandacss', () => { + it('todo', () => { + expect(true).toBeTrue() + }) + }) + + describe('with-sqlite-with-server-action', () => { + it('todo', () => { + expect(true).toBeTrue() + }) + }) + + describe('with-streaming-list', () => { + it('todo', () => { + expect(true).toBeTrue() + }) + }) + + describe('with-suspense', () => { + it('todo', () => { + expect(true).toBeTrue() + }) + }) + + describe('with-tailwindcss', () => { + it('todo', () => { + expect(true).toBeTrue() + }) + }) + + describe('with-view-transitions', () => { + it('todo', () => { + expect(true).toBeTrue() + }) + }) +}) diff --git a/package.json b/package.json index f7fdcd00..0f49013d 100644 --- a/package.json +++ b/package.json @@ -34,7 +34,8 @@ "release-brisa-pandacss:canary": "npm publish --workspace=packages/brisa-pandacss --tag next --access public", "release-adapter-vercel": "bun run --cwd packages/adapter-vercel build && npm publish --workspace=packages/adapter-vercel --access public", "release-adapter-vercel:canary": "bun run --cwd packages/adapter-vercel build && npm publish --workspace=packages/adapter-vercel --tag next --access public", - "test": "bun run --filter 'brisa' test", + "test": "bun test packages/*", + "test:e2e": "bun test ./e2e/examples.test.ts", "test:node": "node --test \"**/*.node-test.js\"", "test:coverage": "bun run --cwd packages/brisa --coverage", "tsc:check": "bun run --cwd packages/brisa tsc:check", From 8270d110ec095036d799d76fb07114c844e14dcf Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Sat, 2 Nov 2024 15:48:22 +0100 Subject: [PATCH 02/22] chore: setup bash --- .github/workflows/test.yml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ade53dac..5feaee17 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,6 +25,12 @@ jobs: with: bun-version: 1.1.35 + - name: Verify Bun installation + run: | + echo "Bun version:" + bun --version + shell: bash + - name: Cache Bun dependencies uses: actions/cache@v3 with: @@ -51,6 +57,7 @@ jobs: steps: - name: Run Bun tests run: bun run test + shell: bash e2e-tests: needs: setup @@ -61,6 +68,7 @@ jobs: steps: - name: Run e2e tests run: bun run test:e2e + shell: bash node-tests: needs: setup @@ -72,3 +80,4 @@ jobs: steps: - name: Run Node.js tests run: bun run test:node + shell: bash From 618a808edafcbad5d27d09009714f12ff1b299ad Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Sat, 2 Nov 2024 15:57:34 +0100 Subject: [PATCH 03/22] chore: fix github action --- .github/workflows/test.yml | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5feaee17..b29319b3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,20 +25,6 @@ jobs: with: bun-version: 1.1.35 - - name: Verify Bun installation - run: | - echo "Bun version:" - bun --version - shell: bash - - - name: Cache Bun dependencies - uses: actions/cache@v3 - with: - path: ~/.bun/install/cache/v1 - key: ${{ runner.os }}-bun-${{ hashFiles('**/package.json') }} - restore-keys: | - ${{ runner.os }}-bun- - - name: Install dependencies run: bun install @@ -55,9 +41,15 @@ jobs: matrix: os: [ubuntu-latest, windows-latest, macos-latest] steps: + - uses: actions/checkout@v4 + + - name: Setup Bun.js + uses: oven-sh/setup-bun@v1 + with: + bun-version: 1.1.34 + - name: Run Bun tests run: bun run test - shell: bash e2e-tests: needs: setup @@ -66,9 +58,15 @@ jobs: matrix: os: [ubuntu-latest, windows-latest, macos-latest] steps: + - uses: actions/checkout@v4 + + - name: Setup Bun.js + uses: oven-sh/setup-bun@v1 + with: + bun-version: 1.1.34 + - name: Run e2e tests run: bun run test:e2e - shell: bash node-tests: needs: setup @@ -78,6 +76,12 @@ jobs: matrix: os: [ubuntu-latest, windows-latest, macos-latest] steps: + - uses: actions/checkout@v4 + + - name: Setup Bun.js + uses: oven-sh/setup-bun@v1 + with: + bun-version: 1.1.34 + - name: Run Node.js tests run: bun run test:node - shell: bash From 41a453881777ad1ee8bef444fc25e00bc3f5e1e9 Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Sat, 2 Nov 2024 20:37:48 +0100 Subject: [PATCH 04/22] chore: use cache on GA jobs --- .github/workflows/test.yml | 40 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b29319b3..7c399259 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,6 +16,16 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Cache dependencies + uses: actions/cache@v3 + with: + path: | + ~/.bun + node_modules + key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }} + restore-keys: | + ${{ runner.os }}-bun- + - name: Setup Node.js uses: actions/setup-node@v3 with: @@ -43,6 +53,16 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Restore cache + uses: actions/cache@v3 + with: + path: | + ~/.bun + node_modules + key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }} + restore-keys: | + ${{ runner.os }}-bun- + - name: Setup Bun.js uses: oven-sh/setup-bun@v1 with: @@ -60,6 +80,16 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Restore cache + uses: actions/cache@v3 + with: + path: | + ~/.bun + node_modules + key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }} + restore-keys: | + ${{ runner.os }}-bun- + - name: Setup Bun.js uses: oven-sh/setup-bun@v1 with: @@ -78,6 +108,16 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Restore cache + uses: actions/cache@v3 + with: + path: | + ~/.bun + node_modules + key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }} + restore-keys: | + ${{ runner.os }}-bun- + - name: Setup Bun.js uses: oven-sh/setup-bun@v1 with: From ea17db0da6d62c0268e4a5e38ec94f74145f527b Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Sat, 2 Nov 2024 20:49:41 +0100 Subject: [PATCH 05/22] chore: update package.json script --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 0f49013d..1687e91a 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "release-adapter-vercel:canary": "bun run --cwd packages/adapter-vercel build && npm publish --workspace=packages/adapter-vercel --tag next --access public", "test": "bun test packages/*", "test:e2e": "bun test ./e2e/examples.test.ts", - "test:node": "node --test \"**/*.node-test.js\"", + "test:node": "node --test packages/**/*.node-test.js", "test:coverage": "bun run --cwd packages/brisa --coverage", "tsc:check": "bun run --cwd packages/brisa tsc:check", "update-version": "bun run scripts/update-brisa-version.ts", From d0743ee0a81f0a3f1e9c77756607758403cdd894 Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Sat, 2 Nov 2024 20:55:37 +0100 Subject: [PATCH 06/22] chore: change cache to artifact --- .github/workflows/test.yml | 51 +++++++++++++------------------------- 1 file changed, 17 insertions(+), 34 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7c399259..c47c9946 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,16 +16,6 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Cache dependencies - uses: actions/cache@v3 - with: - path: | - ~/.bun - node_modules - key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }} - restore-keys: | - ${{ runner.os }}-bun- - - name: Setup Node.js uses: actions/setup-node@v3 with: @@ -43,6 +33,14 @@ jobs: bun run build bun run create-brisa:build + - name: Save node_modules and build output + uses: actions/upload-artifact@v3 + with: + name: build-artifacts + path: | + node_modules + packages + bun-tests: needs: setup runs-on: ${{ matrix.os }} @@ -53,15 +51,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Restore cache - uses: actions/cache@v3 + - name: Restore node_modules and build output + uses: actions/download-artifact@v3 with: - path: | - ~/.bun - node_modules - key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }} - restore-keys: | - ${{ runner.os }}-bun- + name: build-artifacts - name: Setup Bun.js uses: oven-sh/setup-bun@v1 @@ -80,15 +73,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Restore cache - uses: actions/cache@v3 + - name: Restore node_modules and build output + uses: actions/download-artifact@v3 with: - path: | - ~/.bun - node_modules - key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }} - restore-keys: | - ${{ runner.os }}-bun- + name: build-artifacts - name: Setup Bun.js uses: oven-sh/setup-bun@v1 @@ -108,15 +96,10 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Restore cache - uses: actions/cache@v3 + - name: Restore node_modules and build output + uses: actions/download-artifact@v3 with: - path: | - ~/.bun - node_modules - key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }} - restore-keys: | - ${{ runner.os }}-bun- + name: build-artifacts - name: Setup Bun.js uses: oven-sh/setup-bun@v1 From 5fd9a89ed5b5f3d8a2c1b73ee5169a7622a13958 Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Sat, 2 Nov 2024 21:11:56 +0100 Subject: [PATCH 07/22] Revert "chore: change cache to artifact" This reverts commit 987a02c2fbbbc4ae9ab633c22ba736eb3ea8ff66. --- .github/workflows/test.yml | 51 +++++++++++++++++++++++++------------- 1 file changed, 34 insertions(+), 17 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c47c9946..7c399259 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -16,6 +16,16 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Cache dependencies + uses: actions/cache@v3 + with: + path: | + ~/.bun + node_modules + key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }} + restore-keys: | + ${{ runner.os }}-bun- + - name: Setup Node.js uses: actions/setup-node@v3 with: @@ -33,14 +43,6 @@ jobs: bun run build bun run create-brisa:build - - name: Save node_modules and build output - uses: actions/upload-artifact@v3 - with: - name: build-artifacts - path: | - node_modules - packages - bun-tests: needs: setup runs-on: ${{ matrix.os }} @@ -51,10 +53,15 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Restore node_modules and build output - uses: actions/download-artifact@v3 + - name: Restore cache + uses: actions/cache@v3 with: - name: build-artifacts + path: | + ~/.bun + node_modules + key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }} + restore-keys: | + ${{ runner.os }}-bun- - name: Setup Bun.js uses: oven-sh/setup-bun@v1 @@ -73,10 +80,15 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Restore node_modules and build output - uses: actions/download-artifact@v3 + - name: Restore cache + uses: actions/cache@v3 with: - name: build-artifacts + path: | + ~/.bun + node_modules + key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }} + restore-keys: | + ${{ runner.os }}-bun- - name: Setup Bun.js uses: oven-sh/setup-bun@v1 @@ -96,10 +108,15 @@ jobs: steps: - uses: actions/checkout@v4 - - name: Restore node_modules and build output - uses: actions/download-artifact@v3 + - name: Restore cache + uses: actions/cache@v3 with: - name: build-artifacts + path: | + ~/.bun + node_modules + key: ${{ runner.os }}-bun-${{ hashFiles('**/bun.lockb') }} + restore-keys: | + ${{ runner.os }}-bun- - name: Setup Bun.js uses: oven-sh/setup-bun@v1 From 89bf1559800e91675fb809e33939a1753527bb3f Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Sat, 2 Nov 2024 21:18:16 +0100 Subject: [PATCH 08/22] chore: add temporal debug --- .github/workflows/test.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 7c399259..5ec9d048 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -123,5 +123,7 @@ jobs: with: bun-version: 1.1.34 + - name: Debug glob expansion + run: echo packages/**/*.node-test.js - name: Run Node.js tests run: bun run test:node From 52e80699475771c7983d7235a70b94bf4ea62be1 Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Sat, 2 Nov 2024 21:54:08 +0100 Subject: [PATCH 09/22] chore: udpdate debug --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 5ec9d048..ebeeba4c 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -124,6 +124,6 @@ jobs: bun-version: 1.1.34 - name: Debug glob expansion - run: echo packages/**/*.node-test.js + run: ls -la - name: Run Node.js tests run: bun run test:node From 73e0132b2f063db92a96102e15b199285dea5ffa Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Sat, 2 Nov 2024 21:57:42 +0100 Subject: [PATCH 10/22] chore: update debug --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ebeeba4c..2e43ac68 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -124,6 +124,6 @@ jobs: bun-version: 1.1.34 - name: Debug glob expansion - run: ls -la + run: ls -la packages/brisa/src/cli/serve/node-serve - name: Run Node.js tests run: bun run test:node From 8a7ba9b60e22fafe473805c2c60ccd4903c56da0 Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Sat, 2 Nov 2024 22:04:18 +0100 Subject: [PATCH 11/22] fix: fix script --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1687e91a..4d15f1e2 100644 --- a/package.json +++ b/package.json @@ -36,7 +36,7 @@ "release-adapter-vercel:canary": "bun run --cwd packages/adapter-vercel build && npm publish --workspace=packages/adapter-vercel --tag next --access public", "test": "bun test packages/*", "test:e2e": "bun test ./e2e/examples.test.ts", - "test:node": "node --test packages/**/*.node-test.js", + "test:node": "find packages -name '*.node-test.js' -exec node --test {} +", "test:coverage": "bun run --cwd packages/brisa --coverage", "tsc:check": "bun run --cwd packages/brisa tsc:check", "update-version": "bun run scripts/update-brisa-version.ts", From 64f84fbea83fd4dd31f2ebcca060530e1a6e3e45 Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Sat, 2 Nov 2024 22:51:22 +0100 Subject: [PATCH 12/22] chore: update pipeline --- .github/workflows/test.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 2e43ac68..b4539b11 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -118,10 +118,10 @@ jobs: restore-keys: | ${{ runner.os }}-bun- - - name: Setup Bun.js - uses: oven-sh/setup-bun@v1 + - name: Setup Node.js + uses: actions/setup-node@v3 with: - bun-version: 1.1.34 + node-version: "22" - name: Debug glob expansion run: ls -la packages/brisa/src/cli/serve/node-serve From ac099918e49834007c81a3be594aae74d5a56107 Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Sat, 2 Nov 2024 23:37:32 +0100 Subject: [PATCH 13/22] chore: try again --- .github/workflows/test.yml | 36 +++++++++++++++++++----------------- 1 file changed, 19 insertions(+), 17 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b4539b11..edc07e3f 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -53,6 +53,11 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Setup Bun.js + uses: oven-sh/setup-bun@v1 + with: + bun-version: 1.1.34 + - name: Restore cache uses: actions/cache@v3 with: @@ -63,11 +68,6 @@ jobs: restore-keys: | ${{ runner.os }}-bun- - - name: Setup Bun.js - uses: oven-sh/setup-bun@v1 - with: - bun-version: 1.1.34 - - name: Run Bun tests run: bun run test @@ -79,6 +79,10 @@ jobs: os: [ubuntu-latest, windows-latest, macos-latest] steps: - uses: actions/checkout@v4 + - name: Setup Bun.js + uses: oven-sh/setup-bun@v1 + with: + bun-version: 1.1.34 - name: Restore cache uses: actions/cache@v3 @@ -90,11 +94,6 @@ jobs: restore-keys: | ${{ runner.os }}-bun- - - name: Setup Bun.js - uses: oven-sh/setup-bun@v1 - with: - bun-version: 1.1.34 - - name: Run e2e tests run: bun run test:e2e @@ -108,6 +107,16 @@ jobs: steps: - uses: actions/checkout@v4 + - name: Setup Node.js + uses: actions/setup-node@v3 + with: + node-version: "22" + + - name: Setup Bun.js + uses: oven-sh/setup-bun@v1 + with: + bun-version: 1.1.34 + - name: Restore cache uses: actions/cache@v3 with: @@ -118,12 +127,5 @@ jobs: restore-keys: | ${{ runner.os }}-bun- - - name: Setup Node.js - uses: actions/setup-node@v3 - with: - node-version: "22" - - - name: Debug glob expansion - run: ls -la packages/brisa/src/cli/serve/node-serve - name: Run Node.js tests run: bun run test:node From 327e725a2d7e713174294198e0bd8db9aa8da7cb Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Mon, 4 Nov 2024 12:25:34 +0100 Subject: [PATCH 14/22] chore: do build in each job --- .github/workflows/test.yml | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index edc07e3f..73c18129 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -38,11 +38,6 @@ jobs: - name: Install dependencies run: bun install - - name: Build project - run: | - bun run build - bun run create-brisa:build - bun-tests: needs: setup runs-on: ${{ matrix.os }} @@ -68,6 +63,11 @@ jobs: restore-keys: | ${{ runner.os }}-bun- + - name: Build project + run: | + bun run build + bun run create-brisa:build + - name: Run Bun tests run: bun run test @@ -94,6 +94,10 @@ jobs: restore-keys: | ${{ runner.os }}-bun- + - name: Build project + run: | + bun run build + - name: Run e2e tests run: bun run test:e2e @@ -127,5 +131,10 @@ jobs: restore-keys: | ${{ runner.os }}-bun- + - name: Build project + run: | + bun run build + bun run create-brisa:build + - name: Run Node.js tests run: bun run test:node From 4e4bd2d74515c3aa41802df61021f1eff29e2f69 Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Mon, 4 Nov 2024 13:18:40 +0100 Subject: [PATCH 15/22] test: init e2e with simple test --- .github/workflows/test.yml | 5 +- bun.lockb | Bin 133064 -> 133448 bytes e2e/examples.test.ts | 241 +++++++++++++++++++++++++++++++------ package.json | 3 +- 4 files changed, 212 insertions(+), 37 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 73c18129..a728a976 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -95,8 +95,9 @@ jobs: ${{ runner.os }}-bun- - name: Build project - run: | - bun run build + run: bunx playwright install + - run: bunx playwright install-deps + - run: bun run build - name: Run e2e tests run: bun run test:e2e diff --git a/bun.lockb b/bun.lockb index f60b36a5e6ff7385b5c413497c743824089fc6b0..6c1992b4de5858c8983a74c8f43c3e4d03d36196 100755 GIT binary patch delta 19854 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 delta 19507 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 A_5c6? diff --git a/e2e/examples.test.ts b/e2e/examples.test.ts index bc00d8ca..30b94bc2 100644 --- a/e2e/examples.test.ts +++ b/e2e/examples.test.ts @@ -1,71 +1,244 @@ -import { describe, it , expect } from 'bun:test' +import { describe, it , expect, beforeAll, afterAll } from 'bun:test' +import { $, spawn } from 'bun' import fs from 'node:fs' import path from 'node:path' +import { chromium, firefox, webkit } from "playwright"; + +const browsers = [chromium, firefox, webkit] describe('e2e examples', () => { describe('with-api-routes', () => { - it('todo', () => { - expect(true).toBeTrue() - }) + const { setup, teardown } = prepareProject('with-api-routes') + + beforeAll(setup); + afterAll(teardown); + + for (const browserType of browsers) { + it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { + const browser = await browserType.launch(); + const page = await browser.newPage(); + const response = await page.goto('http://localhost:3000'); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue("content-type")).toContain("text/html"); + await browser.close(); + }); + } }) describe('with-elysia', () => { - it('todo', () => { - expect(true).toBeTrue() - }) + const { setup, teardown } = prepareProject('with-elysia') + + beforeAll(setup); + afterAll(teardown); + + for (const browserType of browsers) { + it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { + const browser = await browserType.launch(); + const page = await browser.newPage(); + const response = await page.goto('http://localhost:3000'); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue("content-type")).toContain("text/html"); + await browser.close(); + }); + } }) describe('with-external-web-component', () => { - it('todo', () => { - expect(true).toBeTrue() - }) + const { setup, teardown } = prepareProject('with-elysia') + + beforeAll(setup); + afterAll(teardown); + + for (const browserType of browsers) { + it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { + const browser = await browserType.launch(); + const page = await browser.newPage(); + const response = await page.goto('http://localhost:3000'); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue("content-type")).toContain("text/html"); + await browser.close(); + }); + } }) describe('with-i18n', () => { - it('todo', () => { - expect(true).toBeTrue() - }) + const { setup, teardown } = prepareProject('with-i18n') + + beforeAll(setup); + afterAll(teardown); + + for (const browserType of browsers) { + it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { + const browser = await browserType.launch(); + const page = await browser.newPage(); + const response = await page.goto('http://localhost:3000'); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue("content-type")).toContain("text/html"); + await browser.close(); + }); + } }) describe('with-middleware', () => { - it('todo', () => { - expect(true).toBeTrue() - }) + const { setup, teardown } = prepareProject('with-middleware') + + beforeAll(setup); + afterAll(teardown); + + for (const browserType of browsers) { + it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { + const browser = await browserType.launch(); + const page = await browser.newPage(); + const response = await page.goto('http://localhost:3000'); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue("content-type")).toContain("text/html"); + await browser.close(); + }); + } }) describe('with-pandacss', () => { - it('todo', () => { - expect(true).toBeTrue() - }) + const { setup, teardown } = prepareProject('with-pandacss') + + beforeAll(setup); + afterAll(teardown); + + for (const browserType of browsers) { + it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { + const browser = await browserType.launch(); + const page = await browser.newPage(); + const response = await page.goto('http://localhost:3000'); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue("content-type")).toContain("text/html"); + await browser.close(); + }); + } }) describe('with-sqlite-with-server-action', () => { - it('todo', () => { - expect(true).toBeTrue() - }) + const { setup, teardown } = prepareProject('with-sqlite-with-server-action') + + beforeAll(setup); + afterAll(teardown); + + for (const browserType of browsers) { + it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { + const browser = await browserType.launch(); + const page = await browser.newPage(); + const response = await page.goto('http://localhost:3000'); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue("content-type")).toContain("text/html"); + await browser.close(); + }); + } }) describe('with-streaming-list', () => { - it('todo', () => { - expect(true).toBeTrue() - }) + const { setup, teardown } = prepareProject('with-streaming-list') + + beforeAll(setup); + afterAll(teardown); + + for (const browserType of browsers) { + it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { + const browser = await browserType.launch(); + const page = await browser.newPage(); + const response = await page.goto('http://localhost:3000'); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue("content-type")).toContain("text/html"); + await browser.close(); + }); + } }) describe('with-suspense', () => { - it('todo', () => { - expect(true).toBeTrue() - }) + const { setup, teardown } = prepareProject('with-suspense') + + beforeAll(setup); + afterAll(teardown); + + for (const browserType of browsers) { + it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { + const browser = await browserType.launch(); + const page = await browser.newPage(); + const response = await page.goto('http://localhost:3000'); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue("content-type")).toContain("text/html"); + await browser.close(); + }); + } }) describe('with-tailwindcss', () => { - it('todo', () => { - expect(true).toBeTrue() - }) + const { setup, teardown } = prepareProject('with-tailwindcss') + + beforeAll(setup); + afterAll(teardown); + + for (const browserType of browsers) { + it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { + const browser = await browserType.launch(); + const page = await browser.newPage(); + const response = await page.goto('http://localhost:3000'); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue("content-type")).toContain("text/html"); + await browser.close(); + }); + } }) describe('with-view-transitions', () => { - it('todo', () => { - expect(true).toBeTrue() - }) + const { setup, teardown } = prepareProject('with-view-transitions') + + beforeAll(setup); + afterAll(teardown); + + for (const browserType of browsers) { + it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { + const browser = await browserType.launch(); + const page = await browser.newPage(); + const response = await page.goto('http://localhost:3000'); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue("content-type")).toContain("text/html"); + await browser.close(); + }); + } }) }) + +function prepareProject(exampleName: string) { + let serverProcess + + async function setup() { + const exampleDir = path.join(import.meta.dir, '..', 'examples', exampleName); + + console.log(`✅ Setting up ${exampleName} example...`); + await $`cd ${exampleDir} && bun i && bun run build`; + + serverProcess = spawn({ + cmd: ["bun", "start"], + cwd: exampleDir, + stdout: "inherit", + stderr: "inherit", + }); + + await Bun.sleep(1000); + } + + async function teardown() { + await serverProcess.kill() + } + + return { setup, teardown } +} diff --git a/package.json b/package.json index 4d15f1e2..9fe96bf1 100644 --- a/package.json +++ b/package.json @@ -56,6 +56,7 @@ }, "devDependencies": { "@biomejs/biome": "1.9.4", - "husky": "9.1.6" + "husky": "9.1.6", + "playwright": "1.48.2" } } From 196db698f2baf8e179da8af4d8a16516a7dd40f0 Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Thu, 7 Nov 2024 00:17:52 +0100 Subject: [PATCH 16/22] feat: simplify test --- e2e/examples.test.ts | 257 ++++++++----------------------------------- 1 file changed, 43 insertions(+), 214 deletions(-) diff --git a/e2e/examples.test.ts b/e2e/examples.test.ts index 30b94bc2..2a561f0d 100644 --- a/e2e/examples.test.ts +++ b/e2e/examples.test.ts @@ -1,225 +1,55 @@ import { describe, it , expect, beforeAll, afterAll } from 'bun:test' import { $, spawn } from 'bun' -import fs from 'node:fs' import path from 'node:path' import { chromium, firefox, webkit } from "playwright"; const browsers = [chromium, firefox, webkit] +const timeout = 30000 +const examples = [ + { name: 'with-api-routes' }, + { name: 'with-elysia' }, + { name: 'with-external-web-component' }, + { name: 'with-i18n' }, + { name: 'with-middleware' }, + { name: 'with-pandacss' }, + { name: 'with-sqlite-with-server-action' }, + { name: 'with-streaming-list' }, + { name: 'with-suspense' }, + { name: 'with-tailwindcss' }, + { name: 'with-view-transitions' } +] describe('e2e examples', () => { - describe('with-api-routes', () => { - const { setup, teardown } = prepareProject('with-api-routes') - - beforeAll(setup); - afterAll(teardown); - - for (const browserType of browsers) { - it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { - const browser = await browserType.launch(); - const page = await browser.newPage(); - const response = await page.goto('http://localhost:3000'); - expect(response).not.toBeNull(); - expect(response!.status()).toBe(200); - expect(await response!.headerValue("content-type")).toContain("text/html"); - await browser.close(); - }); - } - }) - - describe('with-elysia', () => { - const { setup, teardown } = prepareProject('with-elysia') - - beforeAll(setup); - afterAll(teardown); - - for (const browserType of browsers) { - it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { - const browser = await browserType.launch(); - const page = await browser.newPage(); - const response = await page.goto('http://localhost:3000'); - expect(response).not.toBeNull(); - expect(response!.status()).toBe(200); - expect(await response!.headerValue("content-type")).toContain("text/html"); - await browser.close(); - }); - } - }) - - describe('with-external-web-component', () => { - const { setup, teardown } = prepareProject('with-elysia') - - beforeAll(setup); - afterAll(teardown); - - for (const browserType of browsers) { - it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { - const browser = await browserType.launch(); - const page = await browser.newPage(); - const response = await page.goto('http://localhost:3000'); - expect(response).not.toBeNull(); - expect(response!.status()).toBe(200); - expect(await response!.headerValue("content-type")).toContain("text/html"); - await browser.close(); - }); - } - }) - - describe('with-i18n', () => { - const { setup, teardown } = prepareProject('with-i18n') - - beforeAll(setup); - afterAll(teardown); - - for (const browserType of browsers) { - it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { - const browser = await browserType.launch(); - const page = await browser.newPage(); - const response = await page.goto('http://localhost:3000'); - expect(response).not.toBeNull(); - expect(response!.status()).toBe(200); - expect(await response!.headerValue("content-type")).toContain("text/html"); - await browser.close(); - }); - } - }) - - describe('with-middleware', () => { - const { setup, teardown } = prepareProject('with-middleware') - - beforeAll(setup); - afterAll(teardown); - - for (const browserType of browsers) { - it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { - const browser = await browserType.launch(); - const page = await browser.newPage(); - const response = await page.goto('http://localhost:3000'); - expect(response).not.toBeNull(); - expect(response!.status()).toBe(200); - expect(await response!.headerValue("content-type")).toContain("text/html"); - await browser.close(); - }); - } - }) - - describe('with-pandacss', () => { - const { setup, teardown } = prepareProject('with-pandacss') - - beforeAll(setup); - afterAll(teardown); - - for (const browserType of browsers) { - it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { - const browser = await browserType.launch(); - const page = await browser.newPage(); - const response = await page.goto('http://localhost:3000'); - expect(response).not.toBeNull(); - expect(response!.status()).toBe(200); - expect(await response!.headerValue("content-type")).toContain("text/html"); - await browser.close(); - }); - } - }) - - describe('with-sqlite-with-server-action', () => { - const { setup, teardown } = prepareProject('with-sqlite-with-server-action') - - beforeAll(setup); - afterAll(teardown); - - for (const browserType of browsers) { - it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { - const browser = await browserType.launch(); - const page = await browser.newPage(); - const response = await page.goto('http://localhost:3000'); - expect(response).not.toBeNull(); - expect(response!.status()).toBe(200); - expect(await response!.headerValue("content-type")).toContain("text/html"); - await browser.close(); - }); - } - }) - - describe('with-streaming-list', () => { - const { setup, teardown } = prepareProject('with-streaming-list') - - beforeAll(setup); - afterAll(teardown); - - for (const browserType of browsers) { - it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { - const browser = await browserType.launch(); - const page = await browser.newPage(); - const response = await page.goto('http://localhost:3000'); - expect(response).not.toBeNull(); - expect(response!.status()).toBe(200); - expect(await response!.headerValue("content-type")).toContain("text/html"); - await browser.close(); - }); - } - }) - - describe('with-suspense', () => { - const { setup, teardown } = prepareProject('with-suspense') - - beforeAll(setup); - afterAll(teardown); - - for (const browserType of browsers) { - it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { - const browser = await browserType.launch(); - const page = await browser.newPage(); - const response = await page.goto('http://localhost:3000'); - expect(response).not.toBeNull(); - expect(response!.status()).toBe(200); - expect(await response!.headerValue("content-type")).toContain("text/html"); - await browser.close(); - }); - } - }) - - describe('with-tailwindcss', () => { - const { setup, teardown } = prepareProject('with-tailwindcss') - - beforeAll(setup); - afterAll(teardown); - - for (const browserType of browsers) { - it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { - const browser = await browserType.launch(); - const page = await browser.newPage(); - const response = await page.goto('http://localhost:3000'); - expect(response).not.toBeNull(); - expect(response!.status()).toBe(200); - expect(await response!.headerValue("content-type")).toContain("text/html"); - await browser.close(); - }); - } - }) - - describe('with-view-transitions', () => { - const { setup, teardown } = prepareProject('with-view-transitions') - - beforeAll(setup); - afterAll(teardown); - - for (const browserType of browsers) { - it(`should load home page with status 200 and HTML content on ${browserType}`, async () => { - const browser = await browserType.launch(); - const page = await browser.newPage(); - const response = await page.goto('http://localhost:3000'); - expect(response).not.toBeNull(); - expect(response!.status()).toBe(200); - expect(await response!.headerValue("content-type")).toContain("text/html"); - await browser.close(); - }); - } - }) + for (const example of examples) { + describe(example.name, () => { + const { setup, teardown, origin } = prepareProject(example.name); + + beforeAll(setup); + afterAll(teardown); + + for (const browserType of browsers) { + it(`should load home page with status 200 and HTML content on ${browserType.name()}`, async () => { + const browser = await browserType.launch(); + try { + const page = await browser.newPage(); + const response = await page.goto(origin, { timeout }); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue("content-type")).toContain("text/html"); + } finally { + await browser.close(); + } + }); + } + }); + } }) function prepareProject(exampleName: string) { let serverProcess + globalThis.currentPort = globalThis.currentPort ? globalThis.currentPort + 1 : 3000 + async function setup() { const exampleDir = path.join(import.meta.dir, '..', 'examples', exampleName); @@ -227,18 +57,17 @@ function prepareProject(exampleName: string) { await $`cd ${exampleDir} && bun i && bun run build`; serverProcess = spawn({ - cmd: ["bun", "start"], + cmd: ["bun", "start", "-p", globalThis.currentPort.toString()], cwd: exampleDir, stdout: "inherit", stderr: "inherit", }); - - await Bun.sleep(1000); } async function teardown() { - await serverProcess.kill() + console.log(`✅ Tearing down ${exampleName} example...`); + await serverProcess.kill('SIGINT') } - return { setup, teardown } + return { setup, teardown, origin: `http://localhost:${globalThis.currentPort}` } } From 5a1b0bb519b2213138fd5a5c5697d40a336a70de Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Thu, 7 Nov 2024 16:44:18 +0100 Subject: [PATCH 17/22] fix: fix e2e --- biome.json | 2 +- e2e/__snapshots__/examples.test.ts.snap | 63 ++++++++++++ e2e/examples.test.ts | 126 ++++++++++++++++-------- 3 files changed, 148 insertions(+), 43 deletions(-) create mode 100644 e2e/__snapshots__/examples.test.ts.snap diff --git a/biome.json b/biome.json index a1acc1d3..e5e39ea4 100644 --- a/biome.json +++ b/biome.json @@ -1,7 +1,7 @@ { "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json", "files": { - "include": ["packages", "scripts", "docs", "examples"], + "include": ["packages", "scripts", "docs", "examples", "e2e"], "ignore": [ "**/out/*", "**/out-*/*", diff --git a/e2e/__snapshots__/examples.test.ts.snap b/e2e/__snapshots__/examples.test.ts.snap new file mode 100644 index 00000000..59a82d60 --- /dev/null +++ b/e2e/__snapshots__/examples.test.ts.snap @@ -0,0 +1,63 @@ +// Bun Snapshot v1, https://goo.gl/fbAQLP + +exports[`e2e example with-api-routes chrome should load home page with status 200 and HTML content 1`] = `"

Example with API Routes

Web Component consuming the API:

Choose an animal:

✏️ Change this page on

src/pages/about/index.tsx

✏️ Change the API on

src/api/animal

✏️ Change the Web Component on

src/web-components/choose-animal.tsx
"`; + +exports[`e2e example with-api-routes firefox should load home page with status 200 and HTML content 1`] = `"

Example with API Routes

Web Component consuming the API:

Choose an animal:

✏️ Change this page on

src/pages/about/index.tsx

✏️ Change the API on

src/api/animal

✏️ Change the Web Component on

src/web-components/choose-animal.tsx
"`; + +exports[`e2e example with-api-routes safari should load home page with status 200 and HTML content 1`] = `"

Example with API Routes

Web Component consuming the API:

Choose an animal:

✏️ Change this page on

src/pages/about/index.tsx

✏️ Change the API on

src/api/animal

✏️ Change the Web Component on

src/web-components/choose-animal.tsx
"`; + +exports[`e2e example with-elysia chrome should load home page with status 200 and HTML content 1`] = `"

Example with API Routes

Web Component consuming the API:

Choose an animal:

✏️ Change this page on

src/pages/about/index.tsx

✏️ Change the API on

src/api/animal

✏️ Change the Web Component on

src/web-components/choose-animal.tsx
"`; + +exports[`e2e example with-elysia firefox should load home page with status 200 and HTML content 1`] = `"

Example with API Routes

Web Component consuming the API:

Choose an animal:

✏️ Change this page on

src/pages/about/index.tsx

✏️ Change the API on

src/api/animal

✏️ Change the Web Component on

src/web-components/choose-animal.tsx
"`; + +exports[`e2e example with-external-web-component chrome should load home page with status 200 and HTML content 1`] = `"

Example with API Routes

Web Component consuming the API:

Choose an animal:

✏️ Change this page on

src/pages/about/index.tsx

✏️ Change the API on

src/api/animal

✏️ Change the Web Component on

src/web-components/choose-animal.tsx
"`; + +exports[`e2e example with-external-web-component firefox should load home page with status 200 and HTML content 1`] = `"

Example with API Routes

Web Component consuming the API:

Choose an animal:

✏️ Change this page on

src/pages/about/index.tsx

✏️ Change the API on

src/api/animal

✏️ Change the Web Component on

src/web-components/choose-animal.tsx
"`; + +exports[`e2e example with-external-web-component safari should load home page with status 200 and HTML content 1`] = `"

Example with API Routes

Web Component consuming the API:

Choose an animal:

✏️ Change this page on

src/pages/about/index.tsx

✏️ Change the API on

src/api/animal

✏️ Change the Web Component on

src/web-components/choose-animal.tsx
"`; + +exports[`e2e example with-i18n chrome should load home page with status 200 and HTML content 1`] = `"

Welcome to i18n!

✏️ Change this page on

src/pages/index.tsx

Counters

Server counter

37
🌐 Cambia a Español
"`; + +exports[`e2e example with-i18n firefox should load home page with status 200 and HTML content 1`] = `"

Welcome to i18n!

✏️ Change this page on

src/pages/index.tsx

Counters

Server counter

37
🌐 Cambia a Español
"`; + +exports[`e2e example with-i18n safari should load home page with status 200 and HTML content 1`] = `"

Welcome to i18n!

✏️ Change this page on

src/pages/index.tsx

Counters

Server counter

37
🌐 Cambia a Español
"`; + +exports[`e2e example with-middleware chrome should load home page with status 200 and HTML content 1`] = `"

Middleware Example

✏️ Change the middleware on

src/middleware.ts

Middleware Example: How to Use It

This middleware example allows you to handle specific URL search parameters and respond accordingly. Below is a breakdown of its functionality and how to test it.

Usage

To use the middleware, simply include it in your Brisa project and configure the URL search parameters as described below:

1. Trigger an Error

If the URL contains the parameter ?throws-error=true, the middleware will throw an internal error.

Example: Test internal error

2. Trigger a 404 Not Found

To simulate a "Not Found" response, include the parameter ?throws-not-found=true in the URL. This will automatically trigger a 404 response.

Example: Test 404 Not Found

3. Redirect to /about

If the URL contains ?redirect-to-about=true, the middleware will redirect to the /about page with a 301 status code.

Example: Redirect to /about

4. Navigate to Another URL

In this scenario it does exactly the same as a redirect. The difference is that “navigate” function can be used on both the server and the client.

By using the parameter ?navigate= followed by the desired URL, the middleware will navigate to the provided destination. For example, if you want to navigate to /about, you can use:

?navigate=/about

Example: Navigate to /about

How It Works

The middleware processes the incoming request based on the final URL of the request context, checking for specific query parameters in the URL. It uses Brisa's navigate and notFound functions to handle navigation and 404 errors, and it uses the standard Response object to handle redirects.

Feel free to modify the URL parameters to test the middleware's behavior in your environment.

"`; + +exports[`e2e example with-middleware firefox should load home page with status 200 and HTML content 1`] = `"

Middleware Example

✏️ Change the middleware on

src/middleware.ts

Middleware Example: How to Use It

This middleware example allows you to handle specific URL search parameters and respond accordingly. Below is a breakdown of its functionality and how to test it.

Usage

To use the middleware, simply include it in your Brisa project and configure the URL search parameters as described below:

1. Trigger an Error

If the URL contains the parameter ?throws-error=true, the middleware will throw an internal error.

Example: Test internal error

2. Trigger a 404 Not Found

To simulate a "Not Found" response, include the parameter ?throws-not-found=true in the URL. This will automatically trigger a 404 response.

Example: Test 404 Not Found

3. Redirect to /about

If the URL contains ?redirect-to-about=true, the middleware will redirect to the /about page with a 301 status code.

Example: Redirect to /about

4. Navigate to Another URL

In this scenario it does exactly the same as a redirect. The difference is that “navigate” function can be used on both the server and the client.

By using the parameter ?navigate= followed by the desired URL, the middleware will navigate to the provided destination. For example, if you want to navigate to /about, you can use:

?navigate=/about

Example: Navigate to /about

How It Works

The middleware processes the incoming request based on the final URL of the request context, checking for specific query parameters in the URL. It uses Brisa's navigate and notFound functions to handle navigation and 404 errors, and it uses the standard Response object to handle redirects.

Feel free to modify the URL parameters to test the middleware's behavior in your environment.

"`; + +exports[`e2e example with-middleware safari should load home page with status 200 and HTML content 1`] = `"

Middleware Example

✏️ Change the middleware on

src/middleware.ts

Middleware Example: How to Use It

This middleware example allows you to handle specific URL search parameters and respond accordingly. Below is a breakdown of its functionality and how to test it.

Usage

To use the middleware, simply include it in your Brisa project and configure the URL search parameters as described below:

1. Trigger an Error

If the URL contains the parameter ?throws-error=true, the middleware will throw an internal error.

Example: Test internal error

2. Trigger a 404 Not Found

To simulate a "Not Found" response, include the parameter ?throws-not-found=true in the URL. This will automatically trigger a 404 response.

Example: Test 404 Not Found

3. Redirect to /about

If the URL contains ?redirect-to-about=true, the middleware will redirect to the /about page with a 301 status code.

Example: Redirect to /about

4. Navigate to Another URL

In this scenario it does exactly the same as a redirect. The difference is that “navigate” function can be used on both the server and the client.

By using the parameter ?navigate= followed by the desired URL, the middleware will navigate to the provided destination. For example, if you want to navigate to /about, you can use:

?navigate=/about

Example: Navigate to /about

How It Works

The middleware processes the incoming request based on the final URL of the request context, checking for specific query parameters in the URL. It uses Brisa's navigate and notFound functions to handle navigation and 404 errors, and it uses the standard Response object to handle redirects.

Feel free to modify the URL parameters to test the middleware's behavior in your environment.

"`; + +exports[`e2e example with-pandacss chrome should load home page with status 200 and HTML content 1`] = `"
"`; + +exports[`e2e example with-pandacss firefox should load home page with status 200 and HTML content 1`] = `"
"`; + +exports[`e2e example with-pandacss safari should load home page with status 200 and HTML content 1`] = `"
"`; + +exports[`e2e example with-sqlite-with-server-action chrome should load home page with status 200 and HTML content 1`] = `"

SQLite Example

✏️ Change the queries on

src/pages/index.tsx

Movies

  • Kill Bill (2025)
  • Kill bill (2024)
  • Kill bill (2024)
  • Kill bill (2024)

Insert a Movie

"`; + +exports[`e2e example with-sqlite-with-server-action firefox should load home page with status 200 and HTML content 1`] = `"

SQLite Example

✏️ Change the queries on

src/pages/index.tsx

Movies

  • Kill Bill (2025)
  • Kill bill (2024)
  • Kill bill (2024)
  • Kill bill (2024)

Insert a Movie

"`; + +exports[`e2e example with-sqlite-with-server-action safari should load home page with status 200 and HTML content 1`] = `"

SQLite Example

✏️ Change the queries on

src/pages/index.tsx

Movies

  • Kill Bill (2025)
  • Kill bill (2024)
  • Kill bill (2024)
  • Kill bill (2024)

Insert a Movie

"`; + +exports[`e2e example with-streaming-list chrome should load home page with status 200 and HTML content 1`] = `"

Welcome to Brisa

✏️ Change this list on

src/components/list-in-streaming.tsx

Streaming Slow List

  • 101ecea7-8c90-4410-980a-c257216ec505
  • 8efab736-a08f-4634-9589-7e9098e3ce0c
  • ea8b41bc-ad87-463b-82a1-c88ef1effdeb
  • d8752710-cb6d-44f4-a9bc-36232e44b231
  • 539eaeaf-6f38-442d-a70e-4fd57fd842f3
  • 28d5b47f-4770-4583-a32e-b60562dc5d95
"`; + +exports[`e2e example with-streaming-list firefox should load home page with status 200 and HTML content 1`] = `"

Welcome to Brisa

✏️ Change this list on

src/components/list-in-streaming.tsx

Streaming Slow List

  • d4a27797-d110-40ca-bf37-b728cc9bc92d
  • 8d9a8068-9b2f-49d7-9374-df022a78945e
  • 6fb65d59-e04e-46d5-96eb-31c33bd773d6
  • cb9c7ad9-9829-46d5-85e3-92eebd7282a2
  • db23b0fd-31d4-404c-a0d7-4f43115b9598
  • 263c6441-7753-4059-a514-e54157c96c5e
"`; + +exports[`e2e example with-streaming-list safari should load home page with status 200 and HTML content 1`] = `"

Welcome to Brisa

✏️ Change this list on

src/components/list-in-streaming.tsx

Streaming Slow List

  • d3509e64-dda8-45fd-8148-198ea9ef2667
  • 70f2eecd-fb15-4e45-a444-678ddf3cb437
  • 6d336e40-d605-47e6-a8e5-261452493890
  • 2649e020-b30f-47ac-9c68-8a5b26dcf28e
  • 7e18e4e5-1b41-41ab-af20-0f13b4781357
  • a526350c-e4cc-47c5-afc2-62378b4d5c1d
"`; + +exports[`e2e example with-suspense chrome should load home page with status 200 and HTML content 1`] = `"

Welcome to Brisa

✏️ Change this page on

src/pages/index.tsx

Counters

Server counter

37
"`; + +exports[`e2e example with-suspense firefox should load home page with status 200 and HTML content 1`] = `"

Welcome to Brisa

✏️ Change this page on

src/pages/index.tsx

Counters

Server counter

37
"`; + +exports[`e2e example with-suspense safari should load home page with status 200 and HTML content 1`] = `"

Welcome to Brisa

✏️ Change this page on

src/pages/index.tsx

Counters

Server counter

37
"`; + +exports[`e2e example with-tailwindcss chrome should load home page with status 200 and HTML content 1`] = `"

Brisa - Poke

An example using Tailwind CSS with Brisa.

Edit src/pages/index.tsx.

"`; + +exports[`e2e example with-tailwindcss firefox should load home page with status 200 and HTML content 1`] = `"

Brisa - Poke

An example using Tailwind CSS with Brisa.

Edit src/pages/index.tsx.

"`; + +exports[`e2e example with-tailwindcss safari should load home page with status 200 and HTML content 1`] = `"

Brisa - Poke

An example using Tailwind CSS with Brisa.

Edit src/pages/index.tsx.

"`; + +exports[`e2e example with-view-transitions chrome should load home page with status 200 and HTML content 1`] = `"

Brisa - Poke

An example using View Transitions with Brisa.

"`; + +exports[`e2e example with-view-transitions firefox should load home page with status 200 and HTML content 1`] = `"

Brisa - Poke

An example using View Transitions with Brisa.

"`; diff --git a/e2e/examples.test.ts b/e2e/examples.test.ts index 2a561f0d..2de3d1c0 100644 --- a/e2e/examples.test.ts +++ b/e2e/examples.test.ts @@ -1,10 +1,22 @@ -import { describe, it , expect, beforeAll, afterAll } from 'bun:test' -import { $, spawn } from 'bun' -import path from 'node:path' -import { chromium, firefox, webkit } from "playwright"; +import { + describe, + beforeAll, + afterAll, + afterEach, + beforeEach, + expect, + it, +} from 'bun:test'; +import { $, spawn } from 'bun'; +import path from 'node:path'; +import { Browser, chromium, firefox, Page, webkit } from 'playwright'; -const browsers = [chromium, firefox, webkit] -const timeout = 30000 +const engine: Record = { + chrome: chromium, + firefox: firefox, + safari: webkit, +}; +const timeout = 30000; const examples = [ { name: 'with-api-routes' }, { name: 'with-elysia' }, @@ -16,58 +28,88 @@ const examples = [ { name: 'with-streaming-list' }, { name: 'with-suspense' }, { name: 'with-tailwindcss' }, - { name: 'with-view-transitions' } -] - -describe('e2e examples', () => { - for (const example of examples) { - describe(example.name, () => { - const { setup, teardown, origin } = prepareProject(example.name); - - beforeAll(setup); - afterAll(teardown); - - for (const browserType of browsers) { - it(`should load home page with status 200 and HTML content on ${browserType.name()}`, async () => { - const browser = await browserType.launch(); - try { - const page = await browser.newPage(); - const response = await page.goto(origin, { timeout }); - expect(response).not.toBeNull(); - expect(response!.status()).toBe(200); - expect(await response!.headerValue("content-type")).toContain("text/html"); - } finally { - await browser.close(); - } + { name: 'with-view-transitions' }, +]; + +describe.each(examples)('e2e example', (example) => { + describe(example.name, () => { + const { setup, teardown, origin } = prepareProject(example.name); + + beforeAll(setup); + afterAll(teardown); + + describe.each(['chrome', 'firefox', 'safari'])('%s', (browserName) => { + let browser: Browser; + let page: Page; + + beforeAll(async () => { + browser = await engine[browserName].launch(); + }); + + beforeEach(async () => { + page = await browser.newPage(); + }); + + afterAll(async () => { + await browser?.close?.(); + }); + + afterEach(async () => { + await page?.close?.(); + }); + + it(`should load home page with status 200 and HTML content`, async () => { + const response = await page.goto(origin, { + waitUntil: 'load', + timeout, }); - } + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue('content-type')).toContain( + 'text/html', + ); + expect(await (await page.$('body'))?.innerHTML()).toMatchSnapshot(); + }); }); - } -}) + }); +}); function prepareProject(exampleName: string) { - let serverProcess + let serverProcess; - globalThis.currentPort = globalThis.currentPort ? globalThis.currentPort + 1 : 3000 + globalThis.currentPort = globalThis.currentPort + ? globalThis.currentPort + 1 + : 3000; async function setup() { - const exampleDir = path.join(import.meta.dir, '..', 'examples', exampleName); + const exampleDir = path.join( + import.meta.dir, + '..', + 'examples', + exampleName, + ); - console.log(`✅ Setting up ${exampleName} example...`); + console.log(`\t→ Setting up ${exampleName} example...`); await $`cd ${exampleDir} && bun i && bun run build`; serverProcess = spawn({ - cmd: ["bun", "start", "-p", globalThis.currentPort.toString()], + cmd: ['bun', 'start', '-p', globalThis.currentPort.toString()], cwd: exampleDir, - stdout: "inherit", - stderr: "inherit", + stdout: 'inherit', + stderr: 'inherit', }); + + await Bun.sleep(2000); } async function teardown() { - console.log(`✅ Tearing down ${exampleName} example...`); - await serverProcess.kill('SIGINT') + console.log(`\t→ Tearing down ${exampleName} example...`); + await serverProcess.kill('SIGINT'); } - return { setup, teardown, origin: `http://localhost:${globalThis.currentPort}` } + return { + setup, + teardown, + origin: `http://localhost:${globalThis.currentPort}`, + }; } From a4765046fb28c4541ee2d98042fbb79519a5fd4a Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Sun, 10 Nov 2024 14:42:03 +0100 Subject: [PATCH 18/22] test(e2e): kill all bun process at end --- e2e/__snapshots__/examples.test.ts.snap | 63 ---------------------- e2e/examples.test.ts | 69 +++++-------------------- e2e/kill.ts | 9 ++++ e2e/preload.ts | 63 ++++++++++++++++++++++ package.json | 2 +- 5 files changed, 86 insertions(+), 120 deletions(-) delete mode 100644 e2e/__snapshots__/examples.test.ts.snap create mode 100644 e2e/kill.ts create mode 100644 e2e/preload.ts diff --git a/e2e/__snapshots__/examples.test.ts.snap b/e2e/__snapshots__/examples.test.ts.snap deleted file mode 100644 index 59a82d60..00000000 --- a/e2e/__snapshots__/examples.test.ts.snap +++ /dev/null @@ -1,63 +0,0 @@ -// Bun Snapshot v1, https://goo.gl/fbAQLP - -exports[`e2e example with-api-routes chrome should load home page with status 200 and HTML content 1`] = `"

Example with API Routes

Web Component consuming the API:

Choose an animal:

✏️ Change this page on

src/pages/about/index.tsx

✏️ Change the API on

src/api/animal

✏️ Change the Web Component on

src/web-components/choose-animal.tsx
"`; - -exports[`e2e example with-api-routes firefox should load home page with status 200 and HTML content 1`] = `"

Example with API Routes

Web Component consuming the API:

Choose an animal:

✏️ Change this page on

src/pages/about/index.tsx

✏️ Change the API on

src/api/animal

✏️ Change the Web Component on

src/web-components/choose-animal.tsx
"`; - -exports[`e2e example with-api-routes safari should load home page with status 200 and HTML content 1`] = `"

Example with API Routes

Web Component consuming the API:

Choose an animal:

✏️ Change this page on

src/pages/about/index.tsx

✏️ Change the API on

src/api/animal

✏️ Change the Web Component on

src/web-components/choose-animal.tsx
"`; - -exports[`e2e example with-elysia chrome should load home page with status 200 and HTML content 1`] = `"

Example with API Routes

Web Component consuming the API:

Choose an animal:

✏️ Change this page on

src/pages/about/index.tsx

✏️ Change the API on

src/api/animal

✏️ Change the Web Component on

src/web-components/choose-animal.tsx
"`; - -exports[`e2e example with-elysia firefox should load home page with status 200 and HTML content 1`] = `"

Example with API Routes

Web Component consuming the API:

Choose an animal:

✏️ Change this page on

src/pages/about/index.tsx

✏️ Change the API on

src/api/animal

✏️ Change the Web Component on

src/web-components/choose-animal.tsx
"`; - -exports[`e2e example with-external-web-component chrome should load home page with status 200 and HTML content 1`] = `"

Example with API Routes

Web Component consuming the API:

Choose an animal:

✏️ Change this page on

src/pages/about/index.tsx

✏️ Change the API on

src/api/animal

✏️ Change the Web Component on

src/web-components/choose-animal.tsx
"`; - -exports[`e2e example with-external-web-component firefox should load home page with status 200 and HTML content 1`] = `"

Example with API Routes

Web Component consuming the API:

Choose an animal:

✏️ Change this page on

src/pages/about/index.tsx

✏️ Change the API on

src/api/animal

✏️ Change the Web Component on

src/web-components/choose-animal.tsx
"`; - -exports[`e2e example with-external-web-component safari should load home page with status 200 and HTML content 1`] = `"

Example with API Routes

Web Component consuming the API:

Choose an animal:

✏️ Change this page on

src/pages/about/index.tsx

✏️ Change the API on

src/api/animal

✏️ Change the Web Component on

src/web-components/choose-animal.tsx
"`; - -exports[`e2e example with-i18n chrome should load home page with status 200 and HTML content 1`] = `"

Welcome to i18n!

✏️ Change this page on

src/pages/index.tsx

Counters

Server counter

37
🌐 Cambia a Español
"`; - -exports[`e2e example with-i18n firefox should load home page with status 200 and HTML content 1`] = `"

Welcome to i18n!

✏️ Change this page on

src/pages/index.tsx

Counters

Server counter

37
🌐 Cambia a Español
"`; - -exports[`e2e example with-i18n safari should load home page with status 200 and HTML content 1`] = `"

Welcome to i18n!

✏️ Change this page on

src/pages/index.tsx

Counters

Server counter

37
🌐 Cambia a Español
"`; - -exports[`e2e example with-middleware chrome should load home page with status 200 and HTML content 1`] = `"

Middleware Example

✏️ Change the middleware on

src/middleware.ts

Middleware Example: How to Use It

This middleware example allows you to handle specific URL search parameters and respond accordingly. Below is a breakdown of its functionality and how to test it.

Usage

To use the middleware, simply include it in your Brisa project and configure the URL search parameters as described below:

1. Trigger an Error

If the URL contains the parameter ?throws-error=true, the middleware will throw an internal error.

Example: Test internal error

2. Trigger a 404 Not Found

To simulate a "Not Found" response, include the parameter ?throws-not-found=true in the URL. This will automatically trigger a 404 response.

Example: Test 404 Not Found

3. Redirect to /about

If the URL contains ?redirect-to-about=true, the middleware will redirect to the /about page with a 301 status code.

Example: Redirect to /about

4. Navigate to Another URL

In this scenario it does exactly the same as a redirect. The difference is that “navigate” function can be used on both the server and the client.

By using the parameter ?navigate= followed by the desired URL, the middleware will navigate to the provided destination. For example, if you want to navigate to /about, you can use:

?navigate=/about

Example: Navigate to /about

How It Works

The middleware processes the incoming request based on the final URL of the request context, checking for specific query parameters in the URL. It uses Brisa's navigate and notFound functions to handle navigation and 404 errors, and it uses the standard Response object to handle redirects.

Feel free to modify the URL parameters to test the middleware's behavior in your environment.

"`; - -exports[`e2e example with-middleware firefox should load home page with status 200 and HTML content 1`] = `"

Middleware Example

✏️ Change the middleware on

src/middleware.ts

Middleware Example: How to Use It

This middleware example allows you to handle specific URL search parameters and respond accordingly. Below is a breakdown of its functionality and how to test it.

Usage

To use the middleware, simply include it in your Brisa project and configure the URL search parameters as described below:

1. Trigger an Error

If the URL contains the parameter ?throws-error=true, the middleware will throw an internal error.

Example: Test internal error

2. Trigger a 404 Not Found

To simulate a "Not Found" response, include the parameter ?throws-not-found=true in the URL. This will automatically trigger a 404 response.

Example: Test 404 Not Found

3. Redirect to /about

If the URL contains ?redirect-to-about=true, the middleware will redirect to the /about page with a 301 status code.

Example: Redirect to /about

4. Navigate to Another URL

In this scenario it does exactly the same as a redirect. The difference is that “navigate” function can be used on both the server and the client.

By using the parameter ?navigate= followed by the desired URL, the middleware will navigate to the provided destination. For example, if you want to navigate to /about, you can use:

?navigate=/about

Example: Navigate to /about

How It Works

The middleware processes the incoming request based on the final URL of the request context, checking for specific query parameters in the URL. It uses Brisa's navigate and notFound functions to handle navigation and 404 errors, and it uses the standard Response object to handle redirects.

Feel free to modify the URL parameters to test the middleware's behavior in your environment.

"`; - -exports[`e2e example with-middleware safari should load home page with status 200 and HTML content 1`] = `"

Middleware Example

✏️ Change the middleware on

src/middleware.ts

Middleware Example: How to Use It

This middleware example allows you to handle specific URL search parameters and respond accordingly. Below is a breakdown of its functionality and how to test it.

Usage

To use the middleware, simply include it in your Brisa project and configure the URL search parameters as described below:

1. Trigger an Error

If the URL contains the parameter ?throws-error=true, the middleware will throw an internal error.

Example: Test internal error

2. Trigger a 404 Not Found

To simulate a "Not Found" response, include the parameter ?throws-not-found=true in the URL. This will automatically trigger a 404 response.

Example: Test 404 Not Found

3. Redirect to /about

If the URL contains ?redirect-to-about=true, the middleware will redirect to the /about page with a 301 status code.

Example: Redirect to /about

4. Navigate to Another URL

In this scenario it does exactly the same as a redirect. The difference is that “navigate” function can be used on both the server and the client.

By using the parameter ?navigate= followed by the desired URL, the middleware will navigate to the provided destination. For example, if you want to navigate to /about, you can use:

?navigate=/about

Example: Navigate to /about

How It Works

The middleware processes the incoming request based on the final URL of the request context, checking for specific query parameters in the URL. It uses Brisa's navigate and notFound functions to handle navigation and 404 errors, and it uses the standard Response object to handle redirects.

Feel free to modify the URL parameters to test the middleware's behavior in your environment.

"`; - -exports[`e2e example with-pandacss chrome should load home page with status 200 and HTML content 1`] = `"
"`; - -exports[`e2e example with-pandacss firefox should load home page with status 200 and HTML content 1`] = `"
"`; - -exports[`e2e example with-pandacss safari should load home page with status 200 and HTML content 1`] = `"
"`; - -exports[`e2e example with-sqlite-with-server-action chrome should load home page with status 200 and HTML content 1`] = `"

SQLite Example

✏️ Change the queries on

src/pages/index.tsx

Movies

  • Kill Bill (2025)
  • Kill bill (2024)
  • Kill bill (2024)
  • Kill bill (2024)

Insert a Movie

"`; - -exports[`e2e example with-sqlite-with-server-action firefox should load home page with status 200 and HTML content 1`] = `"

SQLite Example

✏️ Change the queries on

src/pages/index.tsx

Movies

  • Kill Bill (2025)
  • Kill bill (2024)
  • Kill bill (2024)
  • Kill bill (2024)

Insert a Movie

"`; - -exports[`e2e example with-sqlite-with-server-action safari should load home page with status 200 and HTML content 1`] = `"

SQLite Example

✏️ Change the queries on

src/pages/index.tsx

Movies

  • Kill Bill (2025)
  • Kill bill (2024)
  • Kill bill (2024)
  • Kill bill (2024)

Insert a Movie

"`; - -exports[`e2e example with-streaming-list chrome should load home page with status 200 and HTML content 1`] = `"

Welcome to Brisa

✏️ Change this list on

src/components/list-in-streaming.tsx

Streaming Slow List

  • 101ecea7-8c90-4410-980a-c257216ec505
  • 8efab736-a08f-4634-9589-7e9098e3ce0c
  • ea8b41bc-ad87-463b-82a1-c88ef1effdeb
  • d8752710-cb6d-44f4-a9bc-36232e44b231
  • 539eaeaf-6f38-442d-a70e-4fd57fd842f3
  • 28d5b47f-4770-4583-a32e-b60562dc5d95
"`; - -exports[`e2e example with-streaming-list firefox should load home page with status 200 and HTML content 1`] = `"

Welcome to Brisa

✏️ Change this list on

src/components/list-in-streaming.tsx

Streaming Slow List

  • d4a27797-d110-40ca-bf37-b728cc9bc92d
  • 8d9a8068-9b2f-49d7-9374-df022a78945e
  • 6fb65d59-e04e-46d5-96eb-31c33bd773d6
  • cb9c7ad9-9829-46d5-85e3-92eebd7282a2
  • db23b0fd-31d4-404c-a0d7-4f43115b9598
  • 263c6441-7753-4059-a514-e54157c96c5e
"`; - -exports[`e2e example with-streaming-list safari should load home page with status 200 and HTML content 1`] = `"

Welcome to Brisa

✏️ Change this list on

src/components/list-in-streaming.tsx

Streaming Slow List

  • d3509e64-dda8-45fd-8148-198ea9ef2667
  • 70f2eecd-fb15-4e45-a444-678ddf3cb437
  • 6d336e40-d605-47e6-a8e5-261452493890
  • 2649e020-b30f-47ac-9c68-8a5b26dcf28e
  • 7e18e4e5-1b41-41ab-af20-0f13b4781357
  • a526350c-e4cc-47c5-afc2-62378b4d5c1d
"`; - -exports[`e2e example with-suspense chrome should load home page with status 200 and HTML content 1`] = `"

Welcome to Brisa

✏️ Change this page on

src/pages/index.tsx

Counters

Server counter

37
"`; - -exports[`e2e example with-suspense firefox should load home page with status 200 and HTML content 1`] = `"

Welcome to Brisa

✏️ Change this page on

src/pages/index.tsx

Counters

Server counter

37
"`; - -exports[`e2e example with-suspense safari should load home page with status 200 and HTML content 1`] = `"

Welcome to Brisa

✏️ Change this page on

src/pages/index.tsx

Counters

Server counter

37
"`; - -exports[`e2e example with-tailwindcss chrome should load home page with status 200 and HTML content 1`] = `"

Brisa - Poke

An example using Tailwind CSS with Brisa.

Edit src/pages/index.tsx.

"`; - -exports[`e2e example with-tailwindcss firefox should load home page with status 200 and HTML content 1`] = `"

Brisa - Poke

An example using Tailwind CSS with Brisa.

Edit src/pages/index.tsx.

"`; - -exports[`e2e example with-tailwindcss safari should load home page with status 200 and HTML content 1`] = `"

Brisa - Poke

An example using Tailwind CSS with Brisa.

Edit src/pages/index.tsx.

"`; - -exports[`e2e example with-view-transitions chrome should load home page with status 200 and HTML content 1`] = `"

Brisa - Poke

An example using View Transitions with Brisa.

"`; - -exports[`e2e example with-view-transitions firefox should load home page with status 200 and HTML content 1`] = `"

Brisa - Poke

An example using View Transitions with Brisa.

"`; diff --git a/e2e/examples.test.ts b/e2e/examples.test.ts index 2de3d1c0..356f92f1 100644 --- a/e2e/examples.test.ts +++ b/e2e/examples.test.ts @@ -7,7 +7,6 @@ import { expect, it, } from 'bun:test'; -import { $, spawn } from 'bun'; import path from 'node:path'; import { Browser, chromium, firefox, Page, webkit } from 'playwright'; @@ -18,24 +17,23 @@ const engine: Record = { }; const timeout = 30000; const examples = [ - { name: 'with-api-routes' }, - { name: 'with-elysia' }, - { name: 'with-external-web-component' }, - { name: 'with-i18n' }, - { name: 'with-middleware' }, - { name: 'with-pandacss' }, - { name: 'with-sqlite-with-server-action' }, - { name: 'with-streaming-list' }, - { name: 'with-suspense' }, - { name: 'with-tailwindcss' }, - { name: 'with-view-transitions' }, + { id: 'with-api-routes' }, + { id: 'with-elysia' }, + { id: 'with-external-web-component' }, + { id: 'with-i18n' }, + { id: 'with-middleware' }, + { id: 'with-pandacss' }, + { id: 'with-sqlite-with-server-action' }, + { id: 'with-streaming-list' }, + { id: 'with-suspense' }, + { id: 'with-tailwindcss' }, + { id: 'with-view-transitions' }, ]; describe.each(examples)('e2e example', (example) => { - describe(example.name, () => { - const { setup, teardown, origin } = prepareProject(example.name); + describe(example.id, () => { + const { teardown, origin } = globalThis.examples[example.id]; - beforeAll(setup); afterAll(teardown); describe.each(['chrome', 'firefox', 'safari'])('%s', (browserName) => { @@ -68,48 +66,7 @@ describe.each(examples)('e2e example', (example) => { expect(await response!.headerValue('content-type')).toContain( 'text/html', ); - expect(await (await page.$('body'))?.innerHTML()).toMatchSnapshot(); }); }); }); }); - -function prepareProject(exampleName: string) { - let serverProcess; - - globalThis.currentPort = globalThis.currentPort - ? globalThis.currentPort + 1 - : 3000; - - async function setup() { - const exampleDir = path.join( - import.meta.dir, - '..', - 'examples', - exampleName, - ); - - console.log(`\t→ Setting up ${exampleName} example...`); - await $`cd ${exampleDir} && bun i && bun run build`; - - serverProcess = spawn({ - cmd: ['bun', 'start', '-p', globalThis.currentPort.toString()], - cwd: exampleDir, - stdout: 'inherit', - stderr: 'inherit', - }); - - await Bun.sleep(2000); - } - - async function teardown() { - console.log(`\t→ Tearing down ${exampleName} example...`); - await serverProcess.kill('SIGINT'); - } - - return { - setup, - teardown, - origin: `http://localhost:${globalThis.currentPort}`, - }; -} diff --git a/e2e/kill.ts b/e2e/kill.ts new file mode 100644 index 00000000..6b40e8c5 --- /dev/null +++ b/e2e/kill.ts @@ -0,0 +1,9 @@ +import { $ } from 'bun'; + +console.log('🎉 Killing all bun processes...'); + +if (process.platform === 'win32') { + await $`taskkill /IM bun.exe /F`.quiet(); +} else { + await $`pkill -f bun`.quiet(); +} diff --git a/e2e/preload.ts b/e2e/preload.ts new file mode 100644 index 00000000..2c6485ee --- /dev/null +++ b/e2e/preload.ts @@ -0,0 +1,63 @@ +import { readdirSync } from 'node:fs'; +import path from 'node:path'; +import { $, spawn } from 'bun'; + +const examples = readdirSync( + path.join(import.meta.dir, '..', 'examples'), +).filter((d) => d.startsWith('with-')); + +globalThis.examples = {}; + +for (const example of examples) { + const { setup, teardown, origin } = prepareProject(example); + globalThis.examples[example] = { origin, teardown }; + console.log(`\t→ Setting up ${example} example...`); + await setup(); +} + +await Bun.sleep(2000); + +function prepareProject(exampleName: string) { + let serverProcess; + + globalThis.currentPort = globalThis.currentPort + ? globalThis.currentPort + 1 + : 3000; + + async function setup() { + const exampleDir = path.join( + import.meta.dir, + '..', + 'examples', + exampleName, + ); + + console.log(`\t→ Setting up ${exampleName} example...`); + await $`cd ${exampleDir} && bun i && bun run build`; + + serverProcess = spawn({ + cmd: ['bun', 'start', '-p', globalThis.currentPort.toString()], + cwd: exampleDir, + stdout: 'inherit', + stderr: 'inherit', + }); + } + + async function teardown() { + console.log(`\t→ Tearing down ${exampleName} example...`); + await serverProcess.kill('SIGINT'); + } + + return { + setup, + teardown, + origin: `http://localhost:${globalThis.currentPort}`, + }; +} + +process.on('exit', async () => { + console.log('Tearing down all examples...'); + for (const example of examples) { + await globalThis.examples[example].teardown(); + } +}); diff --git a/package.json b/package.json index 9fe96bf1..600317ee 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "release-adapter-vercel": "bun run --cwd packages/adapter-vercel build && npm publish --workspace=packages/adapter-vercel --access public", "release-adapter-vercel:canary": "bun run --cwd packages/adapter-vercel build && npm publish --workspace=packages/adapter-vercel --tag next --access public", "test": "bun test packages/*", - "test:e2e": "bun test ./e2e/examples.test.ts", + "test:e2e": "bun test --preload ./e2e/preload.ts ./e2e/examples.test.ts && bun run ./e2e/kill.ts", "test:node": "find packages -name '*.node-test.js' -exec node --test {} +", "test:coverage": "bun run --cwd packages/brisa --coverage", "tsc:check": "bun run --cwd packages/brisa tsc:check", From 73ddff05dd2d75db830a7eed650b8e83f8098acf Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Sun, 10 Nov 2024 14:51:16 +0100 Subject: [PATCH 19/22] test: improve e2e --- e2e/examples.test.ts | 234 +++++++++++++++++++++++++++++++++++++++---- package.json | 2 +- 2 files changed, 214 insertions(+), 22 deletions(-) diff --git a/e2e/examples.test.ts b/e2e/examples.test.ts index 356f92f1..c7e6badd 100644 --- a/e2e/examples.test.ts +++ b/e2e/examples.test.ts @@ -17,17 +17,215 @@ const engine: Record = { }; const timeout = 30000; const examples = [ - { id: 'with-api-routes' }, - { id: 'with-elysia' }, - { id: 'with-external-web-component' }, - { id: 'with-i18n' }, - { id: 'with-middleware' }, - { id: 'with-pandacss' }, - { id: 'with-sqlite-with-server-action' }, - { id: 'with-streaming-list' }, - { id: 'with-suspense' }, - { id: 'with-tailwindcss' }, - { id: 'with-view-transitions' }, + { + id: 'with-api-routes', + tests: [ + { + title: 'should load home page with status 200 and HTML content', + test: async (page: Page, origin: string) => { + const response = await page.goto(origin, { + waitUntil: 'load', + timeout, + }); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue('content-type')).toContain( + 'text/html', + ); + }, + }, + ], + }, + { + id: 'with-elysia', + tests: [ + { + title: 'should load home page with status 200 and HTML content', + test: async (page: Page, origin: string) => { + const response = await page.goto(origin, { + waitUntil: 'load', + timeout, + }); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue('content-type')).toContain( + 'text/html', + ); + }, + }, + ], + }, + { + id: 'with-external-web-component', + tests: [ + { + title: 'should load home page with status 200 and HTML content', + test: async (page: Page, origin: string) => { + const response = await page.goto(origin, { + waitUntil: 'load', + timeout, + }); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue('content-type')).toContain( + 'text/html', + ); + }, + }, + ], + }, + { + id: 'with-i18n', + tests: [ + { + title: 'should load home page with status 200 and HTML content', + test: async (page: Page, origin: string) => { + const response = await page.goto(origin, { + waitUntil: 'load', + timeout, + }); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue('content-type')).toContain( + 'text/html', + ); + }, + }, + ], + }, + { + id: 'with-middleware', + tests: [ + { + title: 'should load home page with status 200 and HTML content', + test: async (page: Page, origin: string) => { + const response = await page.goto(origin, { + waitUntil: 'load', + timeout, + }); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue('content-type')).toContain( + 'text/html', + ); + }, + }, + ], + }, + { + id: 'with-pandacss', + tests: [ + { + title: 'should load home page with status 200 and HTML content', + test: async (page: Page, origin: string) => { + const response = await page.goto(origin, { + waitUntil: 'load', + timeout, + }); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue('content-type')).toContain( + 'text/html', + ); + }, + }, + ], + }, + { + id: 'with-sqlite-with-server-action', + tests: [ + { + title: 'should load home page with status 200 and HTML content', + test: async (page: Page, origin: string) => { + const response = await page.goto(origin, { + waitUntil: 'load', + timeout, + }); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue('content-type')).toContain( + 'text/html', + ); + }, + }, + ], + }, + { + id: 'with-streaming-list', + tests: [ + { + title: 'should load home page with status 200 and HTML content', + test: async (page: Page, origin: string) => { + const response = await page.goto(origin, { + waitUntil: 'load', + timeout, + }); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue('content-type')).toContain( + 'text/html', + ); + }, + }, + ], + }, + { + id: 'with-suspense', + tests: [ + { + title: 'should load home page with status 200 and HTML content', + test: async (page: Page, origin: string) => { + const response = await page.goto(origin, { + waitUntil: 'load', + timeout, + }); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue('content-type')).toContain( + 'text/html', + ); + }, + }, + ], + }, + { + id: 'with-tailwindcss', + tests: [ + { + title: 'should load home page with status 200 and HTML content', + test: async (page: Page, origin: string) => { + const response = await page.goto(origin, { + waitUntil: 'load', + timeout, + }); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue('content-type')).toContain( + 'text/html', + ); + }, + }, + ], + }, + { + id: 'with-view-transitions', + tests: [ + { + title: 'should load home page with status 200 and HTML content', + test: async (page: Page, origin: string) => { + const response = await page.goto(origin, { + waitUntil: 'load', + timeout, + }); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue('content-type')).toContain( + 'text/html', + ); + }, + }, + ], + }, ]; describe.each(examples)('e2e example', (example) => { @@ -56,17 +254,11 @@ describe.each(examples)('e2e example', (example) => { await page?.close?.(); }); - it(`should load home page with status 200 and HTML content`, async () => { - const response = await page.goto(origin, { - waitUntil: 'load', - timeout, + for (const { title, test } of example.tests) { + it(title, async () => { + await test(page, origin); }); - expect(response).not.toBeNull(); - expect(response!.status()).toBe(200); - expect(await response!.headerValue('content-type')).toContain( - 'text/html', - ); - }); + } }); }); }); diff --git a/package.json b/package.json index 600317ee..b3a17d4a 100644 --- a/package.json +++ b/package.json @@ -35,7 +35,7 @@ "release-adapter-vercel": "bun run --cwd packages/adapter-vercel build && npm publish --workspace=packages/adapter-vercel --access public", "release-adapter-vercel:canary": "bun run --cwd packages/adapter-vercel build && npm publish --workspace=packages/adapter-vercel --tag next --access public", "test": "bun test packages/*", - "test:e2e": "bun test --preload ./e2e/preload.ts ./e2e/examples.test.ts && bun run ./e2e/kill.ts", + "test:e2e": "bun test --preload ./e2e/preload.ts ./e2e/examples.test.ts; bun run ./e2e/kill.ts", "test:node": "find packages -name '*.node-test.js' -exec node --test {} +", "test:coverage": "bun run --cwd packages/brisa --coverage", "tsc:check": "bun run --cwd packages/brisa tsc:check", From eccba80f697cbffa0164573ba5a4c6b1dfe38037 Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Sun, 10 Nov 2024 14:54:14 +0100 Subject: [PATCH 20/22] chore: use bun 1.1.34 on github action --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index a728a976..d7accbea 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -33,7 +33,7 @@ jobs: - name: Setup Bun.js uses: oven-sh/setup-bun@v1 with: - bun-version: 1.1.35 + bun-version: 1.1.34 - name: Install dependencies run: bun install From 5d21aa7e79230ab78e626084f44a831c7a1a540a Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Sun, 10 Nov 2024 15:29:59 +0100 Subject: [PATCH 21/22] test: add process.exit --- e2e/kill.ts | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/e2e/kill.ts b/e2e/kill.ts index 6b40e8c5..45061f78 100644 --- a/e2e/kill.ts +++ b/e2e/kill.ts @@ -2,8 +2,12 @@ import { $ } from 'bun'; console.log('🎉 Killing all bun processes...'); -if (process.platform === 'win32') { - await $`taskkill /IM bun.exe /F`.quiet(); -} else { - await $`pkill -f bun`.quiet(); +try { + if (process.platform === 'win32') { + await $`taskkill /IM bun.exe /F`.quiet(); + } else { + await $`pkill -f bun`.quiet(); + } +} finally { + process.exit(0); } From 2a36ce1cc3cc37314d2d5ed1566508ef04279b17 Mon Sep 17 00:00:00 2001 From: Aral Roca Date: Thu, 14 Nov 2024 23:10:16 +0100 Subject: [PATCH 22/22] feat: add api-routes test --- e2e/examples.test.ts | 39 ++++++++++++++++++++++++++++++++++++--- 1 file changed, 36 insertions(+), 3 deletions(-) diff --git a/e2e/examples.test.ts b/e2e/examples.test.ts index c7e6badd..80560ad2 100644 --- a/e2e/examples.test.ts +++ b/e2e/examples.test.ts @@ -7,7 +7,6 @@ import { expect, it, } from 'bun:test'; -import path from 'node:path'; import { Browser, chromium, firefox, Page, webkit } from 'playwright'; const engine: Record = { @@ -28,12 +27,46 @@ const examples = [ timeout, }); expect(response).not.toBeNull(); - expect(response!.status()).toBe(200); - expect(await response!.headerValue('content-type')).toContain( + expect(response.status()).toBe(200); + expect(await response.headerValue('content-type')).toContain( 'text/html', ); + + const text = await response.text(); + expect(html).toContain('Loading Animals'); + + // Before API call + ['Dog', 'Cat', 'Bird', 'Fish', 'Horse'].forEach((animal) => { + expect(text).not.toContain(animal); + }) + + // After API call + ['Dog', 'Cat', 'Bird', 'Fish', 'Horse'].forEach(async (animal) => { + expect(await page.textContent(`//body[contains(., '${animal}')]`)).toBe(animal); + }) }, }, + { + title: 'should load /api/animal route with status 200 and JSON content', + test: async (page: Page, origin: string) => { + const response = await page.goto(`${origin}/api/animal`, { + waitUntil: 'domcontentloaded', + timeout, + }); + expect(response).not.toBeNull(); + expect(response!.status()).toBe(200); + expect(await response!.headerValue('content-type')).toContain( + 'application/json', + ); + expect(await response!.json()).toEqual([ + { id: '1', name: 'Dog' }, + { id: '2', name: 'Cat' }, + { id: '3', name: 'Bird' }, + { id: '4', name: 'Fish' }, + { id: '5', name: 'Horse' }, + ]); + }, + } ], }, {