diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml
index d6a02a7..88c58f8 100644
--- a/.github/workflows/deploy.yml
+++ b/.github/workflows/deploy.yml
@@ -23,16 +23,19 @@ jobs:
with:
deno-version: v1.x
+ - name: Install Bun
+ uses: oven-sh/setup-bun@v1
+
- name: Install Node.js
uses: actions/setup-node@v4
with:
- node-version: lts/*
+ node-version: 22.x
- - name: Install step
+ - name: Install dependencies
run: npm install --ignore-scripts
- - name: Build step
- run: npm run build
+ - name: Build
+ run: bun run build
- name: Generate .env file
uses: SpicyPizza/create-envfile@v2.0
@@ -40,10 +43,10 @@ jobs:
envkey_DATABASE_URL: ${{ secrets.DATABASE_URL }}
- name: Run migrations
- run: npm run kysely -- migrate:latest
+ run: bun run kysely -- migrate:latest
- name: Run tests
- run: npm run test:ci:npm
+ run: bun run test
- name: Upload coverage deno
uses: codecov/codecov-action@v4
diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml
index 30b1b1b..3e522cc 100644
--- a/.github/workflows/pr.yml
+++ b/.github/workflows/pr.yml
@@ -43,16 +43,19 @@ jobs:
with:
deno-version: v1.x
+ - name: Install Bun
+ uses: oven-sh/setup-bun@v1
+
- name: Install Node.js
uses: actions/setup-node@v4
with:
- node-version: lts/*
+ node-version: 22.x
- - name: Install modules
+ - name: Install dependencies
run: npm install --ignore-scripts
- - name: Build step
- run: npm run build
+ - name: Build
+ run: bun run build
- name: Generate .env file
uses: SpicyPizza/create-envfile@v2.0
@@ -60,10 +63,10 @@ jobs:
envkey_DATABASE_URL: ${{ env.DATABASE_URL }}
- name: Run migrations
- run: npm run kysely -- migrate:latest
+ run: bun run kysely -- migrate:latest
- name: Run tests
- run: npm run test:ci:npm
+ run: bun run test
- name: Upload coverage deno
uses: codecov/codecov-action@v4
diff --git a/README.md b/README.md
index 6d97e71..e4f010a 100644
--- a/README.md
+++ b/README.md
@@ -49,7 +49,7 @@
- [x] Coverage
- [x] Unit
- [ ] Integration
- - [ ] E2E
+ - [x] E2E
- [x] HMR
- [x] RPC
- [x] Admin
diff --git a/api/import-map.production.json b/api/import-map.production.json
index 900a572..be0bd44 100644
--- a/api/import-map.production.json
+++ b/api/import-map.production.json
@@ -1,8 +1,4 @@
{
- "fmt": {
- "singleQuote": true,
- "semiColons": false
- },
"imports": {
"kysely": "npm:kysely@^0.27.4",
"pg": "npm:pg",
diff --git a/bunfig.toml b/bunfig.toml
new file mode 100644
index 0000000..aa19f0d
--- /dev/null
+++ b/bunfig.toml
@@ -0,0 +1,4 @@
+[test]
+preload = "./happydom.ts"
+coverageSkipTestFiles = true
+coverageReporter = ["text", "lcov"]
diff --git a/happydom.ts b/happydom.ts
new file mode 100644
index 0000000..b5b1498
--- /dev/null
+++ b/happydom.ts
@@ -0,0 +1,3 @@
+import { GlobalRegistrator } from "@happy-dom/global-registrator"
+
+GlobalRegistrator.register({ url: 'https://localhost' })
diff --git a/package.json b/package.json
index 4066fdb..47df1bb 100644
--- a/package.json
+++ b/package.json
@@ -8,17 +8,15 @@
"main": "src/client.tsx",
"scripts": {
"build": "vite build",
- "test": "pnpm test:api && pnpm test:web",
- "test:ci": "pnpm test:api:ci && pnpm test:web",
- "test:ci:npm": "npm run test:api:ci && npm run test:web",
- "test:watch": "pnpm test:api:watch & pnpm test:web:watch",
+ "test": "bun run test:api && bun run test:web",
+ "test:watch": "bun run test:api:watch & bun run test:web:watch",
"test:api": "deno test -A --no-lock api",
"test:api:ci": "deno test -A --no-lock --import-map=./api/import-map.production.json --coverage=coverage/deno api",
"test:api:cov": "deno coverage coverage/deno --lcov --output=coverage/lcov-deno.info",
"test:api:watch": "deno test -A --watch --no-lock api & deno -A --no-lock api/test-watch.ts",
- "test:web": "vitest run --coverage",
- "test:web:watch": "vitest --coverage",
- "dev": "pnpm dev:db & pnpm dev:api & pnpm dev:web",
+ "test:web": "bun test --coverage src",
+ "test:web:watch": "bun test --coverage --watch src",
+ "dev": "bun run dev:db & bun run dev:api & bun run dev:web",
"dev:db": "docker compose up",
"dev:api": "deno --watch --unstable-kv -A api/core/server.ts",
"dev:web": "vite",
@@ -27,9 +25,10 @@
"postinstall": "link-local || exit 0"
},
"devDependencies": {
+ "@happy-dom/global-registrator": "^15.7.4",
"@maktouch/kysely-zod-codegen": "^0.5.2",
+ "@types/bun": "^1.1.10",
"@types/node": "^22.7.4",
- "@vitest/coverage-v8": "^2.1.2",
"ambient-dts": "github:stagas/ambient-dts",
"autoprefixer": "^10.4.20",
"jsdom": "^25.0.1",
@@ -39,8 +38,7 @@
"postcss": "^8.4.47",
"tailwindcss": "^3.4.13",
"utils": "github:stagas/utils",
- "vite": "^5.4.8",
- "vitest": "^2.1.1"
+ "vite": "^5.4.8"
},
"dependencies": {
"@types/pg": "^8.11.10",
diff --git a/src/test/e2e.test.tsx b/src/test/e2e.test.tsx
new file mode 100644
index 0000000..e145459
--- /dev/null
+++ b/src/test/e2e.test.tsx
@@ -0,0 +1,37 @@
+import { App } from '../pages/App.tsx'
+import { state } from '../state.ts'
+
+// @ts-ignore
+globalThis.fetch = () => {
+ return { json: () => { } }
+}
+
+describe('App', () => {
+ it('works', () => {
+ const app =
+ expect(app).toBeInstanceOf(Element)
+ })
+
+ it('routes', async () => {
+ const app =
+ expect(app).toBeInstanceOf(Element)
+ state.url = new URL('/about', location.origin)
+ state.url = new URL('/verify-email', location.origin)
+ state.url = new URL('/reset-password', location.origin)
+ })
+
+ it('user', async () => {
+ const app =
+ expect(app).toBeInstanceOf(Element)
+ state.user = null
+ state.user = {
+ nick: 'foo',
+ expires: new Date(),
+ }
+ state.user = {
+ nick: 'foo',
+ expires: new Date(),
+ isAdmin: true
+ }
+ })
+})
diff --git a/vite.config.ts b/vite.config.ts
index d65c740..960f6de 100644
--- a/vite.config.ts
+++ b/vite.config.ts
@@ -1,5 +1,3 @@
-///
-
import fs from 'node:fs'
import os from 'node:os'
import path from 'node:path'
@@ -19,22 +17,6 @@ export default ({ mode }) => {
} : undefined
return defineConfig({
clearScreen: false,
- test: {
- globals: true,
- dir: 'src',
- includeSource: ['src/**/*.{js,jsx,ts,tsx}'],
- environment: 'jsdom',
- coverage: {
- clean: false,
- cleanOnRerun: false,
- include: ['src'],
- reporter: ['lcovonly'],
- reportsDirectory: 'coverage'
- }
- },
- define: {
- 'import.meta.vitest': 'undefined',
- },
server: {
host: true,
fs: {