Skip to content

Commit 492c922

Browse files
authored
Merge pull request #1 from BRIKEV/tutorial
Tutorial
2 parents a79920e + 842d768 commit 492c922

7 files changed

Lines changed: 104 additions & 48 deletions

File tree

.github/workflows/ci.yml

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: CI - PR Tests
2+
3+
on:
4+
pull_request:
5+
branches: [ main ]
6+
7+
jobs:
8+
test:
9+
runs-on: ubuntu-latest
10+
11+
steps:
12+
- name: Checkout repository
13+
uses: actions/checkout@v5
14+
15+
- name: Setup Node.js
16+
uses: actions/setup-node@v5
17+
with:
18+
node-version: 24
19+
cache: 'npm'
20+
21+
- name: Install dependencies
22+
run: npm ci
23+
24+
- name: Start Vite dev server
25+
run: |
26+
nohup npm run dev:ci > vite.log 2>&1 &
27+
npx wait-on http://localhost:5173
28+
env:
29+
CI: true
30+
31+
- name: Run Puppeteer tests (test:ci)
32+
run: npm run test:ci
33+
env:
34+
CI: true
35+
36+
- name: Display coverage
37+
run: |
38+
npm run collect:coverage:text

package-lock.json

Lines changed: 4 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,17 @@
55
"type": "module",
66
"scripts": {
77
"dev": "vite",
8+
"dev:ci": "CI=true VITE_COVERAGE=true vite",
89
"build": "tsc -b && vite build",
910
"lint": "eslint .",
1011
"test": "vitest",
1112
"preview": "vite preview",
1213
"serve": "json-server --watch data/data.json --routes data/routes.json --port 3001",
1314
"serve:dev": "npm-run-all --parallel serve dev",
14-
"collect:coverage": "nyc report --reporter=html --report-dir=coverage --temp-dir=coverage",
15-
"test:ci": "node scripts/run-tests-ci.js"
15+
"test:ci": "node scripts/run-tests-ci.js",
16+
"collect:coverage:html": "npx nyc report --reporter=html --report-dir=coverage",
17+
"collect:coverage:lcov": "npx nyc report --reporter=lcov --report-dir=coverage",
18+
"collect:coverage:text": "npx nyc report --reporter=text --report-dir=coverage"
1619
},
1720
"dependencies": {
1821
"@radix-ui/react-avatar": "^1.1.4",
@@ -32,6 +35,7 @@
3235
"tailwind-merge": "^3.2.0",
3336
"tailwindcss": "^4.1.4",
3437
"tw-animate-css": "^1.2.5",
38+
"twd-js": "^0.8.0",
3539
"zustand": "^5.0.3"
3640
},
3741
"devDependencies": {
@@ -54,7 +58,6 @@
5458
"npm-run-all": "^4.1.5",
5559
"nyc": "^17.1.0",
5660
"puppeteer": "^24.29.1",
57-
"twd-js": "^0.8.0",
5861
"typescript": "~5.7.2",
5962
"typescript-eslint": "^8.26.1",
6063
"vite": "^6.3.1",

scripts/run-tests-ci.js

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
1+
import fs from 'fs';
2+
import path from 'path';
13
import puppeteer from "puppeteer";
24
import { reportResults } from 'twd-js/runner-ci';
35

6+
let __dirname = path.resolve();
7+
48
const browser = await puppeteer.launch({
59
headless: true,
6-
args: ['--lang=es-ES,es'],
10+
args: ['--no-sandbox', '--disable-setuid-sandbox'],
711
});
812
const page = await browser.newPage();
9-
await page.emulateTimezone('Europe/Madrid');
1013
console.time('Total Test Time');
1114
try {
1215
// Navigate to your development server
@@ -40,7 +43,23 @@ try {
4043
// Display results in console
4144
reportResults(handlers, testStatus);
4245

43-
const coverage = await page.evaluate(() => window.__coverage__)
46+
const coverage = await page.evaluate(() => window.__coverage__);
47+
if (coverage) {
48+
console.log('Collecting code coverage data...');
49+
const coverageDir = path.resolve(__dirname, './coverage');
50+
const nycDir = path.resolve(__dirname, './.nyc_output');
51+
if (!fs.existsSync(nycDir)) {
52+
fs.mkdirSync(nycDir);
53+
}
54+
if (!fs.existsSync(coverageDir)) {
55+
fs.mkdirSync(coverageDir);
56+
}
57+
const coveragePath = path.join(nycDir, 'out.json');
58+
fs.writeFileSync(coveragePath, JSON.stringify(coverage));
59+
console.log(`Code coverage data written to ${coveragePath}`);
60+
} else {
61+
console.log('No code coverage data found.');
62+
}
4463

4564
// Exit with appropriate code
4665
const hasFailures = testStatus.some(test => test.status === 'fail');

src/twd-tests/helloWorld.twd.test.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ describe("Hello World Page", () => {
1818
counterButton.should("have.text", "Count is 2");
1919

2020
await userEvent.click(counterButton.el);
21-
console.log(counterButton.el.textContent);
22-
2321
counterButton.should("have.text", "Count is 3");
2422
});
25-
});
23+
});

src/twd-tests/todoList.twd.test.ts

Lines changed: 30 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@ describe("Todo List Page", () => {
1616
});
1717
await twd.visit("/todos");
1818
await twd.waitForRequest("getTodoList");
19-
const todoList = await twd.getAll("[data-testid='todo-item']");
20-
expect(todoList).to.have.length(2);
2119
const todo1Title = await twd.get("[data-testid='todo-title-1']");
2220
todo1Title.should("have.text", "Learn TWD");
2321
const todo2Title = await twd.get("[data-testid='todo-title-2']");
@@ -32,34 +30,6 @@ describe("Todo List Page", () => {
3230
todo2Date.should("have.text", "Date: 2024-12-25");
3331
});
3432

35-
it("should delete a todo", async () => {
36-
await twd.mockRequest("deleteTodo", {
37-
method: "DELETE",
38-
url: "/api/todos/1",
39-
response: null,
40-
status: 200,
41-
});
42-
await twd.mockRequest("getTodoList", {
43-
method: "GET",
44-
url: "/api/todos",
45-
response: todoListMock,
46-
status: 200,
47-
});
48-
await twd.visit("/todos");
49-
const deleteButton = await twd.get("[data-testid='delete-todo-1']");
50-
await twd.mockRequest("getTodoList", {
51-
method: "GET",
52-
url: "/api/todos",
53-
response: todoListMock.filter((todo) => todo.id !== "1"),
54-
status: 200,
55-
});
56-
await userEvent.click(deleteButton.el);
57-
await twd.waitForRequest("deleteTodo");
58-
await twd.waitForRequest("getTodoList");
59-
const todoList = await twd.getAll("[data-testid='todo-item']");
60-
expect(todoList).to.have.length(1);
61-
});
62-
6333
it("should create a todo", async () => {
6434
await twd.mockRequest("createTodo", {
6535
method: "POST",
@@ -75,6 +45,8 @@ describe("Todo List Page", () => {
7545
});
7646
await twd.visit("/todos");
7747
await twd.waitForRequest("getTodoList");
48+
const noTodosMessage = await twd.get("[data-testid='no-todos-message']");
49+
noTodosMessage.should("be.visible");
7850
await twd.mockRequest("getTodoList", {
7951
method: "GET",
8052
url: "/api/todos",
@@ -83,8 +55,6 @@ describe("Todo List Page", () => {
8355
],
8456
status: 200,
8557
});
86-
const noTodosMessage = await twd.get("[data-testid='no-todos-message']");
87-
noTodosMessage.should("be.visible");
8858
const title = await twd.get("input[name='title']");
8959
await userEvent.type(title.el, "Test Todo");
9060
const description = await twd.get("input[name='description']");
@@ -103,4 +73,32 @@ describe("Todo List Page", () => {
10373
const todoList = await twd.getAll("[data-testid='todo-item']");
10474
expect(todoList).to.have.length(1);
10575
});
76+
77+
it("should delete a todo", async () => {
78+
await twd.mockRequest("deleteTodo", {
79+
method: "DELETE",
80+
url: "/api/todos/1",
81+
response: null,
82+
status: 200,
83+
});
84+
await twd.mockRequest("getTodoList", {
85+
method: "GET",
86+
url: "/api/todos",
87+
response: todoListMock,
88+
status: 200,
89+
});
90+
await twd.visit("/todos");
91+
const deleteButton = await twd.get("[data-testid='delete-todo-1']");
92+
await twd.mockRequest("getTodoList", {
93+
method: "GET",
94+
url: "/api/todos",
95+
response: todoListMock.filter((todo) => todo.id !== "1"),
96+
status: 200,
97+
});
98+
await userEvent.click(deleteButton.el);
99+
await twd.waitForRequest("deleteTodo");
100+
await twd.waitForRequest("getTodoList");
101+
const todoList = await twd.getAll("[data-testid='todo-item']");
102+
expect(todoList).to.have.length(1);
103+
});
106104
});

vite.config.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,15 @@ import path from "path"
33
import tailwindcss from "@tailwindcss/vite"
44
import { defineConfig } from 'vite'
55
import react from '@vitejs/plugin-react'
6+
// add plugin for code coverage
67
import istanbul from 'vite-plugin-istanbul';
78

89
// https://vite.dev/config/
910
export default defineConfig({
1011
plugins: [
1112
react(),
1213
tailwindcss(),
14+
// configure istanbul plugin
1315
istanbul({
1416
include: 'src/**/*',
1517
exclude: ['node_modules', 'tests/'],
@@ -27,4 +29,4 @@ export default defineConfig({
2729
ignored: ["**/data/data.json", "**data/routes.json"],
2830
},
2931
},
30-
})
32+
})

0 commit comments

Comments
 (0)