Skip to content

Commit 17983ab

Browse files
authored
Docs/ci example (#71)
* feat(wip): example ci with puppeteer * ci: add job to deploy docs to github pages * docs: getting started improvement * docs: improve writting tests * docs: improve mocking api docs * docs: improve ci docs * docs: improve api doc * docs: improve command docs * docs: improve overall docs and add tutorial * docs: remove old tutorial * docs: improve documentation * docs: add more examples * docs: improve examples
1 parent 15e1298 commit 17983ab

95 files changed

Lines changed: 12908 additions & 5152 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/deploy_docs.yml

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
# Sample workflow for building and deploying a VitePress site to GitHub Pages
2+
#
3+
name: Deploy VitePress TWD docs site to Pages
4+
5+
on:
6+
# Runs on pushes targeting the `main` branch. Change this to `master` if you're
7+
# using the `master` branch as the default branch.
8+
push:
9+
branches: [main]
10+
11+
# Allows you to run this workflow manually from the Actions tab
12+
workflow_dispatch:
13+
14+
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
15+
permissions:
16+
contents: read
17+
pages: write
18+
id-token: write
19+
20+
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
21+
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
22+
concurrency:
23+
group: pages
24+
cancel-in-progress: false
25+
26+
jobs:
27+
# Build job
28+
build:
29+
runs-on: ubuntu-latest
30+
steps:
31+
- name: Checkout
32+
uses: actions/checkout@v4
33+
with:
34+
fetch-depth: 0 # Not needed if lastUpdated is not enabled
35+
# - uses: pnpm/action-setup@v3 # Uncomment this block if you're using pnpm
36+
# with:
37+
# version: 9 # Not needed if you've set "packageManager" in package.json
38+
# - uses: oven-sh/setup-bun@v1 # Uncomment this if you're using Bun
39+
- name: Setup Node
40+
uses: actions/setup-node@v4
41+
with:
42+
node-version: 22
43+
cache: npm # or pnpm / yarn
44+
- name: Setup Pages
45+
uses: actions/configure-pages@v4
46+
- name: Install dependencies
47+
run: npm ci # or pnpm install / yarn install / bun install
48+
- name: Build with VitePress
49+
run: npm run docs:build # or pnpm docs:build / yarn docs:build / bun run docs:build
50+
- name: Upload artifact
51+
uses: actions/upload-pages-artifact@v3
52+
with:
53+
path: .vitepress/dist
54+
55+
# Deployment job
56+
deploy:
57+
environment:
58+
name: github-pages
59+
url: ${{ steps.deployment.outputs.page_url }}
60+
needs: build
61+
runs-on: ubuntu-latest
62+
name: Deploy
63+
steps:
64+
- name: Deploy to GitHub Pages
65+
id: deployment
66+
uses: actions/deploy-pages@v4

docs/.vitepress/config.mts

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ export default defineConfig({
1212
nav: [
1313
{ text: 'Home', link: '/' },
1414
{ text: 'Guide', link: '/getting-started' },
15-
{ text: 'Examples', link: '/examples/' },
15+
{ text: 'Tutorial', link: '/tutorial/' },
1616
{ text: 'API Reference', link: '/api/' }
1717
],
1818

@@ -27,13 +27,16 @@ export default defineConfig({
2727
]
2828
},
2929
{
30-
text: 'Examples',
30+
text: 'Tutorial',
3131
items: [
32-
{ text: 'Overview', link: '/examples/' },
33-
{ text: 'Selectors', link: '/examples/selectors' },
34-
{ text: 'Assertions', link: '/examples/assertions' },
35-
{ text: 'API Mocking', link: '/examples/mocking' },
36-
{ text: 'User Events', link: '/examples/user-events' }
32+
{ text: 'Overview', link: '/tutorial/' },
33+
{ text: 'Installation', link: '/tutorial/installation' },
34+
{ text: 'First Test', link: '/tutorial/first-test' },
35+
{ text: 'Assertions & Navigation', link: '/tutorial/assertions-navigation' },
36+
{ text: 'API Mocking', link: '/tutorial/api-mocking' },
37+
{ text: 'Test Hooks', link: '/tutorial/test-hooks' },
38+
{ text: 'Production Builds', link: '/tutorial/production-builds' },
39+
{ text: 'CI Integration', link: '/tutorial/ci-integration' }
3740
]
3841
},
3942
{

docs/api-mocking.md

Lines changed: 57 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,13 @@
11
# API Mocking
22

3-
TWD provides powerful API mocking capabilities through Mock Service Worker integration, allowing you to test your application with realistic network requests and responses.
3+
TWD provides powerful API mocking capabilities through our own mock service worker integration, allowing you to test your application with realistic network requests and responses.
44

55
## Setup
66

7-
**VIDEO HERE** - *Step-by-step guide to setting up Mock Service Worker with TWD*
8-
97
### 1. Install Mock Service Worker
108

119
First, set up the mock service worker in your project:
1210

13-
**IMAGE HERE** - *Terminal screenshot showing the init command and its output*
14-
1511
```bash
1612
npx twd-js init public
1713
```
@@ -67,8 +63,6 @@ You only need to call `initRequestMocking()` once in your main entry file, not i
6763

6864
## Basic Mocking
6965

70-
**VIDEO HERE** - *Live demonstration of setting up a mock, triggering a request, and seeing the mocked response*
71-
7266
### Simple GET Request
7367

7468
```ts
@@ -87,7 +81,7 @@ describe("User Profile", () => {
8781
}
8882
});
8983

90-
twd.visit("/profile");
84+
await twd.visit("/profile");
9185

9286
// Trigger the request
9387
const loadButton = await twd.get("button[data-testid='load-profile']");
@@ -119,7 +113,7 @@ it("should create new user", async () => {
119113
status: 201
120114
});
121115

122-
twd.visit("/users/new");
116+
await twd.visit("/users/new");
123117

124118
const user = userEvent.setup();
125119

@@ -134,8 +128,7 @@ it("should create new user", async () => {
134128
const rule = await twd.waitForRequest("createUser");
135129

136130
// Check the request body
137-
const requestBody = JSON.parse(rule.request as string);
138-
expect(requestBody).to.deep.equal({
131+
expect(rule.request).to.deep.equal({
139132
name: "Jane Smith",
140133
email: "jane@example.com"
141134
});
@@ -159,7 +152,7 @@ it("should handle dynamic user IDs", async () => {
159152
});
160153

161154
// This will match the pattern
162-
twd.visit("/users/123");
155+
await twd.visit("/users/123");
163156

164157
// Trigger request and verify
165158
const loadButton = await twd.get("button[data-testid='load-user']");
@@ -187,7 +180,7 @@ it("should handle API errors", async () => {
187180
}
188181
});
189182

190-
twd.visit("/user/999");
183+
await twd.visit("/user/999");
191184

192185
const loadButton = await twd.get("button[data-testid='load-user']");
193186
await userEvent.click(loadButton.el);
@@ -220,7 +213,7 @@ it("should handle multiple API calls", async () => {
220213
]
221214
});
222215

223-
twd.visit("/user/123");
216+
await twd.visit("/user/123");
224217

225218
const loadButton = await twd.get("button[data-testid='load-all']");
226219
await userEvent.click(loadButton.el);
@@ -252,7 +245,7 @@ it("should handle changing API responses", async () => {
252245
response: { status: "loading" }
253246
});
254247

255-
twd.visit("/dashboard");
248+
await twd.visit("/dashboard");
256249

257250
const refreshButton = await twd.get("button[data-testid='refresh']");
258251
await userEvent.click(refreshButton.el);
@@ -290,7 +283,7 @@ it("should handle authentication states", async () => {
290283
status: 401
291284
});
292285

293-
twd.visit("/profile");
286+
await twd.visit("/profile");
294287

295288
// Should redirect to login
296289
await twd.wait(100);
@@ -360,9 +353,8 @@ it("should send correct form data", async () => {
360353

361354
// Verify request data
362355
const rule = await twd.waitForRequest("submitForm");
363-
const requestData = JSON.parse(rule.request as string);
364356

365-
expect(requestData).to.deep.equal({
357+
expect(rule.request).to.deep.equal({
366358
email: "test@example.com",
367359
message: "Hello world",
368360
newsletter: true
@@ -449,38 +441,6 @@ it("should have correct mocks configured", async () => {
449441

450442
## Common Patterns
451443

452-
### Loading States
453-
454-
```ts
455-
it("should show loading spinner during API call", async () => {
456-
// Add delay to mock to simulate slow network
457-
await twd.mockRequest("slowRequest", {
458-
method: "GET",
459-
url: "/api/slow",
460-
response: { data: "loaded" }
461-
});
462-
463-
twd.visit("/slow-page");
464-
465-
const loadButton = await twd.get("button[data-testid='load']");
466-
await userEvent.click(loadButton.el);
467-
468-
// Check loading state immediately
469-
const spinner = await twd.get(".loading-spinner");
470-
spinner.should("be.visible");
471-
472-
// Wait for request to complete
473-
await twd.waitForRequest("slowRequest");
474-
475-
// Loading should be gone
476-
spinner.should("not.be.visible");
477-
478-
// Data should be shown
479-
const data = await twd.get("[data-testid='data']");
480-
data.should("contain.text", "loaded");
481-
});
482-
```
483-
484444
### Error Handling
485445

486446
```ts
@@ -495,7 +455,7 @@ it("should display error message on API failure", async () => {
495455
status: 500
496456
});
497457

498-
twd.visit("/data-page");
458+
await twd.visit("/data-page");
499459

500460
const loadButton = await twd.get("button[data-testid='load-data']");
501461
await userEvent.click(loadButton.el);
@@ -529,7 +489,7 @@ it("should handle paginated results", async () => {
529489
pagination: {
530490
page: 1,
531491
hasNext: true,
532-
total: 10
492+
total: 3
533493
}
534494
}
535495
});
@@ -541,17 +501,16 @@ it("should handle paginated results", async () => {
541501
response: {
542502
users: [
543503
{ id: 3, name: "User 3" },
544-
{ id: 4, name: "User 4" }
545504
],
546505
pagination: {
547506
page: 2,
548-
hasNext: true,
549-
total: 10
507+
hasNext: false,
508+
total: 3
550509
}
551510
}
552511
});
553512

554-
twd.visit("/users");
513+
await twd.visit("/users");
555514

556515
// Load first page
557516
await twd.waitForRequest("getPage1");
@@ -567,7 +526,7 @@ it("should handle paginated results", async () => {
567526

568527
// Should now have 4 users total
569528
users = await twd.getAll(".user-item");
570-
expect(users).to.have.length(4);
529+
expect(users).to.have.length(1);
571530
});
572531
```
573532

@@ -610,6 +569,46 @@ twd.mockRequest("getUser", {
610569
});
611570
```
612571

572+
### 3. Mock before request event is fired
573+
574+
```ts
575+
// Good ✅ - mock before request event is fired
576+
await twd.mockRequest("saveUser", {
577+
method: "POST",
578+
url: "/api/users",
579+
response: { id: 1, created: true }
580+
});
581+
582+
await twd.visit("/users/new");
583+
584+
const user = userEvent.setup();
585+
await user.type(await twd.get("#name"), "John Doe");
586+
await user.type(await twd.get("#email"), "john.doe@example.com");
587+
await user.click(await twd.get("button[type='submit']"));
588+
589+
await twd.waitForRequest("saveUser");
590+
591+
const userName = await twd.get("[data-testid='user-name']");
592+
userName.should("have.text", "John Doe");
593+
```
594+
595+
```ts
596+
// Bad ❌ - mock after request event is fired
597+
await twd.visit("/users/new");
598+
599+
const user = userEvent.setup();
600+
await user.type(await twd.get("#name"), "John Doe");
601+
await user.type(await twd.get("#email"), "john.doe@example.com");
602+
await user.click(await twd.get("button[type='submit']"));
603+
// Bad ❌ - mock after request event is fired
604+
twd.mockRequest("saveUser", {
605+
method: "POST",
606+
url: "/api/users",
607+
response: { id: 1 }
608+
});
609+
await twd.waitForRequest("saveUser");
610+
```
611+
613612
### 3. Clean Up Mocks
614613

615614
```ts
@@ -683,6 +682,5 @@ await twd.mockRequest("flexibleMatch", {
683682

684683
## Next Steps
685684

686-
- Explore [Examples](/examples/mocking) for more mocking patterns
687-
- Learn about [User Events](/examples/user-events) for form interactions
685+
- Learn about [User Events in the Tutorial](/tutorial/first-test) for form interactions
688686
- Check the [API Reference](/api/twd-commands) for all mocking methods

0 commit comments

Comments
 (0)