twd-js 1.8.0-beta.1 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +60 -145
- package/dist/bundled.es.js +901 -901
- package/dist/constants/version.d.ts +1 -1
- package/dist/index.cjs.js +32 -32
- package/dist/index.es.js +1265 -1265
- package/dist/mock-sw.js +1 -1
- package/dist/runner.cjs.js +1 -1
- package/dist/runner.es.js +1 -1
- package/dist/ui.cjs.js +1 -1
- package/dist/ui.es.js +1 -1
- package/dist/vite-plugin.cjs.js +1 -1
- package/package.json +1 -1
- /package/dist/{componentMocks-BFMYYH2e.js → componentMocks-B83slL5w.js} +0 -0
- /package/dist/{componentMocks-CwMyWCu5.cjs → componentMocks-BklBTS5K.cjs} +0 -0
- /package/dist/{runner-BmEWmCyd.js → runner-8uKtUFnx.js} +0 -0
- /package/dist/{runner-Dr_mUWED.cjs → runner-ClPPXm0J.cjs} +0 -0
package/README.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# TWD
|
|
1
|
+
# TWD — Test While Developing
|
|
2
2
|
|
|
3
3
|
[](https://github.com/BRIKEV/twd/actions/workflows/ci.yml)
|
|
4
4
|
[](https://www.npmjs.com/package/twd-js)
|
|
@@ -7,184 +7,98 @@
|
|
|
7
7
|
[](https://qlty.sh/gh/BRIKEV/projects/twd)
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
10
|
-
<img src="https://raw.githubusercontent.com/BRIKEV/twd/main/images/twd-skill.gif" alt="TWD running with an AI agent" width="800">
|
|
10
|
+
<img src="https://raw.githubusercontent.com/BRIKEV/twd/main/images/twd-skill.gif" alt="TWD running with an AI agent: tests written and executed in a real browser sidebar" width="800">
|
|
11
11
|
</p>
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
> **Frontend tests that run in your real browser.** Same DOM, same routes, same state as your dev server. For React, Vue, Angular, and Solid.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
## The problem
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
Testing gets pushed to next week, and next week never comes. When it does happen, tests usually run in a different environment from where you're building, so testing feels like overhead the moment you finish a feature.
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
- ⚡ **Instant feedback** as you develop
|
|
21
|
-
- 🔥 **Mock Service Worker** integration for API/request mocking
|
|
22
|
-
- 📝 **Simple, readable test syntax** (inspired by popular test frameworks)
|
|
23
|
-
- 🧩 **Automatic test discovery** with Vite support
|
|
24
|
-
- 🎯 **Testing Library support** - Use `screenDom` for semantic, accessible queries
|
|
25
|
-
- 🛠️ **Works with React** (support for more frameworks coming)
|
|
19
|
+
The tooling pushes you the same way. You end up writing more code for the tests than for the feature itself, between setup, mocks, and helpers. Adding tests starts to feel like shipping a second app on top of the one you already finished.
|
|
26
20
|
|
|
27
|
-
|
|
21
|
+
As AI writes more of your code, the gap widens. Agents generate test files that look correct but never actually execute in a real browser. The mocks those tests rely on quietly drift from the real API over time. Fields get renamed, mocks stay frozen, tests pass, production breaks.
|
|
28
22
|
|
|
29
|
-
|
|
30
|
-
npm install twd-js
|
|
31
|
-
# or
|
|
32
|
-
yarn add twd-js
|
|
33
|
-
# or
|
|
34
|
-
pnpm add twd-js
|
|
35
|
-
```
|
|
36
|
-
|
|
37
|
-
## Quick Start
|
|
23
|
+
## The solution
|
|
38
24
|
|
|
39
|
-
|
|
25
|
+
TWD puts tests inside your dev server. A sidebar appears in your real browser, runs tests against the same DOM your users see, and updates as you code. When you're ready, plug in an AI agent that writes tests, runs them via a WebSocket bridge, and iterates until they pass. When you ship, validate every mock against your OpenAPI spec to catch drift before a user does.
|
|
40
26
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
```ts
|
|
44
|
-
// vite.config.ts
|
|
45
|
-
import { defineConfig } from 'vite';
|
|
46
|
-
import react from '@vitejs/plugin-react'; // or vue, solid, etc.
|
|
47
|
-
import { twd } from 'twd-js/vite-plugin';
|
|
48
|
-
|
|
49
|
-
export default defineConfig({
|
|
50
|
-
plugins: [
|
|
51
|
-
react(),
|
|
52
|
-
twd({
|
|
53
|
-
testFilePattern: '/**/*.twd.test.{ts,tsx}',
|
|
54
|
-
open: true,
|
|
55
|
-
position: 'left',
|
|
56
|
-
}),
|
|
57
|
-
],
|
|
58
|
-
});
|
|
59
|
-
```
|
|
27
|
+
> **Test what you own. Mock what you don't.**
|
|
60
28
|
|
|
61
|
-
|
|
29
|
+
Full pitch and docs at **[twd.dev](https://twd.dev)**.
|
|
62
30
|
|
|
63
|
-
|
|
31
|
+
## Quick start
|
|
64
32
|
|
|
65
33
|
```bash
|
|
66
|
-
|
|
34
|
+
npm install --save-dev twd-js
|
|
67
35
|
```
|
|
68
36
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
If your project doesn't use Vite, initialize TWD manually in your dev entry point:
|
|
72
|
-
|
|
73
|
-
```ts
|
|
74
|
-
// Only load the test sidebar and tests in development mode
|
|
75
|
-
if (import.meta.env.DEV) {
|
|
76
|
-
const { initTWD } = await import('twd-js/bundled');
|
|
77
|
-
const tests = import.meta.glob('./**/*.twd.test.ts');
|
|
78
|
-
|
|
79
|
-
initTWD(tests, {
|
|
80
|
-
open: true,
|
|
81
|
-
position: 'left',
|
|
82
|
-
serviceWorker: true, // Enable request mocking (default: true)
|
|
83
|
-
serviceWorkerUrl: '/mock-sw.js', // Custom service worker path (default: '/mock-sw.js')
|
|
84
|
-
});
|
|
85
|
-
}
|
|
86
|
-
```
|
|
87
|
-
|
|
88
|
-
Check the [Framework Integration Guide](https://brikev.github.io/twd/frameworks) for more details.
|
|
89
|
-
|
|
90
|
-
## Writing Tests
|
|
37
|
+
Add the Vite plugin (auto-loads the sidebar and discovers your test files):
|
|
91
38
|
|
|
92
39
|
```ts
|
|
93
|
-
//
|
|
94
|
-
import {
|
|
95
|
-
import {
|
|
96
|
-
|
|
97
|
-
describe("Hello World Page", () => {
|
|
98
|
-
it("should display the welcome title and counter button", async () => {
|
|
99
|
-
await twd.visit("/");
|
|
100
|
-
|
|
101
|
-
// Use Testing Library queries (Recommended - semantic & accessible)
|
|
102
|
-
const title = screenDom.getByRole("heading", { name: /welcome to twd/i });
|
|
103
|
-
twd.should(title, "be.visible");
|
|
104
|
-
twd.should(title, "have.text", "Welcome to TWD");
|
|
105
|
-
|
|
106
|
-
const counterButton = screenDom.getByRole("button", { name: /count is/i });
|
|
107
|
-
twd.should(counterButton, "be.visible");
|
|
108
|
-
twd.should(counterButton, "have.text", "Count is 0");
|
|
109
|
-
|
|
110
|
-
const user = userEvent.setup();
|
|
111
|
-
await user.click(counterButton);
|
|
112
|
-
twd.should(counterButton, "have.text", "Count is 1");
|
|
113
|
-
|
|
114
|
-
// Alternative: Use TWD's native selectors for direct element access
|
|
115
|
-
// const title = await twd.get("h1");
|
|
116
|
-
// title.should("be.visible").should("have.text", "Welcome to TWD");
|
|
117
|
-
});
|
|
118
|
-
});
|
|
119
|
-
```
|
|
120
|
-
|
|
121
|
-
3. **Run your app** - The TWD sidebar will appear automatically in development mode!
|
|
122
|
-
|
|
123
|
-
<p align="center">
|
|
124
|
-
<img src="https://raw.githubusercontent.com/BRIKEV/twd/main/images/twd_side_bar_success.png" alt="TWD Sidebar in action" width="800">
|
|
125
|
-
</p>
|
|
126
|
-
|
|
127
|
-
## Key Concepts
|
|
128
|
-
|
|
129
|
-
### Element Selection
|
|
130
|
-
|
|
131
|
-
TWD supports two approaches:
|
|
132
|
-
|
|
133
|
-
**Testing Library Queries (Recommended):**
|
|
134
|
-
```ts
|
|
135
|
-
const button = screenDom.getByRole("button", { name: /submit/i });
|
|
136
|
-
twd.should(button, "be.visible");
|
|
137
|
-
```
|
|
40
|
+
// vite.config.ts
|
|
41
|
+
import { defineConfig } from 'vite'
|
|
42
|
+
import { twd } from 'twd-js/vite-plugin'
|
|
138
43
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
button.should("be.visible");
|
|
44
|
+
export default defineConfig({
|
|
45
|
+
plugins: [twd({ open: true })],
|
|
46
|
+
})
|
|
143
47
|
```
|
|
144
48
|
|
|
145
|
-
|
|
49
|
+
Write a test next to your code:
|
|
146
50
|
|
|
147
51
|
```ts
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
52
|
+
// src/App.twd.test.ts
|
|
53
|
+
import { twd, screenDom } from 'twd-js'
|
|
54
|
+
import { describe, it } from 'twd-js/runner'
|
|
55
|
+
|
|
56
|
+
describe('App', () => {
|
|
57
|
+
it('shows the heading', async () => {
|
|
58
|
+
await twd.visit('/')
|
|
59
|
+
const heading = await screenDom.findByRole('heading', { level: 1 })
|
|
60
|
+
twd.should(heading, 'be.visible')
|
|
61
|
+
})
|
|
62
|
+
})
|
|
151
63
|
```
|
|
152
64
|
|
|
153
|
-
|
|
65
|
+
Run `npm run dev` and open the app. The TWD sidebar appears in your browser; click play to run the test.
|
|
154
66
|
|
|
155
|
-
|
|
156
|
-
twd.mockRequest("getUser", {
|
|
157
|
-
method: "GET",
|
|
158
|
-
url: "/api/user",
|
|
159
|
-
response: { id: 1, name: "John" }
|
|
160
|
-
});
|
|
67
|
+
→ **[Full setup guide](https://twd.dev/getting-started)** · **[Framework integration](https://twd.dev/frameworks)** (Angular, non-Vite, Astro, React Router)
|
|
161
68
|
|
|
162
|
-
|
|
163
|
-
```
|
|
69
|
+
## The TWD ecosystem
|
|
164
70
|
|
|
165
|
-
|
|
71
|
+
One package today. The rest when you need it.
|
|
166
72
|
|
|
167
|
-
|
|
73
|
+
| Tool | What it does |
|
|
74
|
+
| --- | --- |
|
|
75
|
+
| **[twd-js](https://twd.dev/twd-js)** | The core sidebar. Frontend tests that run in your real browser. |
|
|
76
|
+
| **[twd-relay](https://twd.dev/twd-relay)** | Token-efficient browser testing for AI agents. Structured pass/fail over WebSocket. No Playwright, no screenshots. |
|
|
77
|
+
| **[twd-cli](https://twd.dev/contract-testing)** | Headless CI runs with coverage and OpenAPI contract validation. |
|
|
168
78
|
|
|
169
|
-
|
|
170
|
-
- [Framework Integration](docs/frameworks.md)
|
|
171
|
-
- [Writing Tests](docs/writing-tests.md)
|
|
172
|
-
- [API Mocking](docs/api-mocking.md)
|
|
79
|
+
## Examples & showcase
|
|
173
80
|
|
|
174
|
-
|
|
81
|
+
- **[twd-shadcn](https://github.com/BRIKEV/twd-shadcn)** — React + shadcn/ui with a [live demo](https://brikev.github.io/twd-shadcn/) you can interact with
|
|
82
|
+
- **[twd-react-router](https://github.com/BRIKEV/twd-react-router)** — React Router (Framework Mode) with `createRoutesStub` and loader mocking
|
|
83
|
+
- **[twd-tanstack-example](https://github.com/BRIKEV/twd-tanstack-example)** — TanStack Router integration
|
|
84
|
+
- **[twd-vue-example](https://github.com/BRIKEV/twd-vue-example)** — Vue 3
|
|
85
|
+
- **[twd-angular-example](https://github.com/BRIKEV/twd-angular-example)** — Angular
|
|
86
|
+
- **[twd-auth0](https://github.com/BRIKEV/twd-auth0)** — Auth0 session mocking
|
|
175
87
|
|
|
176
|
-
|
|
88
|
+
→ **[All examples and community content](https://twd.dev/community)**
|
|
177
89
|
|
|
178
|
-
|
|
179
|
-
- **[Vue Example](https://github.com/BRIKEV/twd-vue-example)** - Vue 3 with advanced scenarios
|
|
180
|
-
- **[Solid Example](https://github.com/BRIKEV/twd-solid-example)** - Solid.js integration
|
|
181
|
-
- **[Angular Example](https://github.com/BRIKEV/twd-angular-example)** - Angular setup
|
|
90
|
+
## Documentation
|
|
182
91
|
|
|
183
|
-
|
|
92
|
+
- **[Getting Started](https://twd.dev/getting-started)** — Install, set up, write your first test
|
|
93
|
+
- **[Writing Tests](https://twd.dev/writing-tests)** — Selectors, assertions, interactions, navigation
|
|
94
|
+
- **[API Mocking](https://twd.dev/api-mocking)** — Mock Service Worker patterns
|
|
95
|
+
- **[AI Integration](https://twd.dev/ai-overview)** — Connect Claude Code (or any agent) via twd-relay
|
|
96
|
+
- **[Contract Testing Setup](https://twd.dev/contract-testing-setup)** — Validate mocks against OpenAPI specs in CI
|
|
97
|
+
- **[API Reference](https://twd.dev/api/)** — Test functions, commands, assertions
|
|
184
98
|
|
|
185
99
|
## Contributing
|
|
186
100
|
|
|
187
|
-
|
|
101
|
+
Open issues or pull requests on [GitHub](https://github.com/BRIKEV/twd). If you're starting out in tech and looking for a beginner-friendly first PR, see the [open issues](https://github.com/BRIKEV/twd/issues). Reach out and the maintainer will help with setup and walk you through it.
|
|
188
102
|
|
|
189
103
|
## Contributors ✨
|
|
190
104
|
|
|
@@ -197,6 +111,7 @@ Contributions are welcome! Please open issues or pull requests on [GitHub](https
|
|
|
197
111
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/kevinccbsg"><img src="https://avatars.githubusercontent.com/u/12685053?v=4?s=100" width="100px;" alt="Kevin Julián Martínez Escobar"/><br /><sub><b>Kevin Julián Martínez Escobar</b></sub></a><br /><a href="https://github.com/BRIKEV/twd/commits?author=kevinccbsg" title="Code">💻</a></td>
|
|
198
112
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/DamonCaos"><img src="https://avatars.githubusercontent.com/u/169996368?v=4?s=100" width="100px;" alt="Javier Rodriguez"/><br /><sub><b>Javier Rodriguez</b></sub></a><br /><a href="https://github.com/BRIKEV/twd/commits?author=DamonCaos" title="Documentation">📖</a></td>
|
|
199
113
|
<td align="center" valign="top" width="14.28%"><a href="https://github.com/codesthenos"><img src="https://avatars.githubusercontent.com/u/166174180?v=4?s=100" width="100px;" alt="Guillermo Ruiz Arranz"/><br /><sub><b>Guillermo Ruiz Arranz</b></sub></a><br /><a href="https://github.com/BRIKEV/twd/commits?author=codesthenos" title="Code">💻</a></td>
|
|
114
|
+
<td align="center" valign="top" width="14.28%"><a href="https://portfolio-pi-ruby-7alj81l6dp.vercel.app/"><img src="https://avatars.githubusercontent.com/u/157389533?v=4?s=100" width="100px;" alt="Roberto Gomez Fabrega"/><br /><sub><b>Roberto Gomez Fabrega</b></sub></a><br /><a href="https://github.com/BRIKEV/twd/commits?author=Rober040992" title="Documentation">📖</a></td>
|
|
200
115
|
</tr>
|
|
201
116
|
</tbody>
|
|
202
117
|
</table>
|
|
@@ -206,8 +121,8 @@ Contributions are welcome! Please open issues or pull requests on [GitHub](https
|
|
|
206
121
|
|
|
207
122
|
<!-- ALL-CONTRIBUTORS-LIST:END -->
|
|
208
123
|
|
|
209
|
-
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind are welcome
|
|
124
|
+
This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind are welcome.
|
|
210
125
|
|
|
211
126
|
## License
|
|
212
127
|
|
|
213
|
-
|
|
128
|
+
[MIT](./LICENSE)
|