frontend-go-live-check 1.4.1 → 1.6.0
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/CHANGELOG.md +14 -0
- package/README.md +125 -32
- package/package.json +1 -1
- package/schema.json +236 -8
- package/src/api/model.mjs +1 -1
- package/src/api/postman-run.mjs +362 -0
- package/src/checks/auth.mjs +1 -1
- package/src/checks/browser.mjs +5 -1
- package/src/checks/code.mjs +91 -3
- package/src/checks/flows.mjs +354 -0
- package/src/checks/load.mjs +81 -35
- package/src/checks/project-tests.mjs +216 -0
- package/src/checks/security.mjs +60 -0
- package/src/checks/sso.mjs +1 -1
- package/src/checks/visual.mjs +7 -2
- package/src/cli/main.mjs +9 -7
- package/src/commands/ci.mjs +18 -18
- package/src/commands/doctor.mjs +9 -8
- package/src/commands/init.mjs +34 -27
- package/src/commands/login.mjs +14 -11
- package/src/commands/run.mjs +57 -14
- package/src/core/config.mjs +49 -22
- package/src/core/explain.mjs +52 -2
- package/src/core/login.mjs +1 -1
- package/src/core/project.mjs +1 -1
- package/src/core/routes.mjs +1 -1
- package/src/core/rules.mjs +102 -1
- package/src/core/session.mjs +1 -1
- package/src/export/docx.mjs +4 -3
- package/src/export/model.mjs +48 -8
- package/src/export/pdf.mjs +4 -3
- package/src/report/report.mjs +102 -23
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.5.0
|
|
4
|
+
|
|
5
|
+
- **Your own tests in the same report**: unit tests (Vitest, Jest, Karma or `npm test`) with code coverage, and end-to-end tests (Playwright Test, Cypress) against the production build. A new area: *Tests, user flows and business rules*.
|
|
6
|
+
- **User flows and business rules without code** in `go-live-check/flows.json`: open, fill, select, click, see, url and API checks (status and JSON values), on every screen size. A broken business rule is a blocker.
|
|
7
|
+
- **Forms filled with valid data** and sent: they must save and tell the user (only on this computer or allowed hosts).
|
|
8
|
+
- **Postman collection run in order** with its `pm.test` scripts and the variables carried between requests; `api.variables` for `{{variables}}`.
|
|
9
|
+
- **Load profiles**: `light`, `standard` (50 users, 1 minute) and `stress` (finds the breaking point); `--load <profile>`.
|
|
10
|
+
- **Security**: CORS (which websites may read the API) and the HTTPS certificate and TLS version.
|
|
11
|
+
- **Code quality**: `lint` / `typecheck` scripts, unused and outdated libraries, very long files, copied code.
|
|
12
|
+
- **One folder for everything**: `go-live-check/` holds the settings (`config.json`), the test passwords (`.env`), the API files (`api/`), the design baseline (`baseline/`), the report (`report/`) and a saved sign-in (`session.json`), with its own `.gitignore`. `init` creates it. Projects with the older root files keep working; the README shows how to move.
|
|
13
|
+
- Every section of the HTML report opens and closes (accordion), with **Expand all** and **Collapse all**.
|
|
14
|
+
- The date and time the report was created are at the top of the HTML report, on the PDF and Word cover, and in the page header.
|
|
15
|
+
- Visual changes show the real pages: **Before** (the approved look), **Now** and **Changes** side by side; in each finding, Actual is the page now and Expected is the approved look.
|
|
16
|
+
|
|
3
17
|
## 1.4.1
|
|
4
18
|
|
|
5
19
|
- Problems are grouped **by type** (Functionality, Design, Accessibility, Performance, Sign-in, APIs, Security, SEO, Code) in the HTML report, the PDF and the Word file, most serious first in each group.
|
package/README.md
CHANGED
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
|
|
19
19
|
<p align="center">
|
|
20
20
|
<a href="#quick-start">Quick start</a> ·
|
|
21
|
+
<a href="#files-everything-in-one-folder">Files</a> ·
|
|
21
22
|
<a href="#sign-in-email-google-microsoft-uae-pass">Sign-in</a> ·
|
|
22
23
|
<a href="#what-it-checks">What it checks</a> ·
|
|
23
24
|
<a href="#how-it-works">How it works</a> ·
|
|
@@ -38,11 +39,11 @@ npx frontend-go-live-check init
|
|
|
38
39
|
npm run go-live
|
|
39
40
|
```
|
|
40
41
|
|
|
41
|
-
That's it. The result is `go-live-report/index.html`, plus a PDF and a Word file to share with your team.
|
|
42
|
+
That's it. The result is `go-live-check/report/index.html`, plus a PDF and a Word file to share with your team.
|
|
42
43
|
|
|
43
44
|
`init` adds the `go-live` scripts and a settings file, and downloads the test browser. It never overwrites anything.
|
|
44
45
|
|
|
45
|
-
Have an API? Save your Postman collection as **`api/postman_collection.json`** (or your OpenAPI file as `api/openapi.json`) and the API tests run too.
|
|
46
|
+
Have an API? Save your Postman collection as **`go-live-check/api/postman_collection.json`** (or your OpenAPI file as `go-live-check/api/openapi.json`) and the API tests run too.
|
|
46
47
|
|
|
47
48
|
<p align="center">
|
|
48
49
|
<img src="https://unpkg.com/frontend-go-live-check@1/docs/terminal.png" alt="Terminal output: NOT READY, 2 blocker, 7 major, 5 minor, with a score per area" width="760">
|
|
@@ -50,6 +51,54 @@ Have an API? Save your Postman collection as **`api/postman_collection.json`** (
|
|
|
50
51
|
|
|
51
52
|
---
|
|
52
53
|
|
|
54
|
+
## Files: everything in one folder
|
|
55
|
+
|
|
56
|
+
Everything the tool uses or makes is in **one `go-live-check/` folder** at the root of your project. `init` creates it.
|
|
57
|
+
|
|
58
|
+
```text
|
|
59
|
+
my-project/
|
|
60
|
+
├── go-live-check/
|
|
61
|
+
│ ├── config.json ← the settings (all optional)
|
|
62
|
+
│ ├── .env ← test passwords (Git ignores it)
|
|
63
|
+
│ ├── .env.example ← the names to fill in (committed)
|
|
64
|
+
│ ├── api/
|
|
65
|
+
│ │ ├── postman_collection.json ← your Postman collection
|
|
66
|
+
│ │ ├── postman_environment.json ← optional: its environment
|
|
67
|
+
│ │ └── openapi.json ← or/and your OpenAPI file
|
|
68
|
+
│ ├── flows.json ← your user journeys and business rules (optional)
|
|
69
|
+
│ ├── baseline/ ← the approved look of every page (commit it)
|
|
70
|
+
│ ├── report/ ← the results: HTML, PDF, Word, zip (Git ignores it)
|
|
71
|
+
│ ├── session.json ← a saved sign-in, after `login` (Git ignores it)
|
|
72
|
+
│ └── .gitignore ← keeps .env, report/ and session.json out of Git
|
|
73
|
+
├── src/
|
|
74
|
+
└── package.json
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
| Commit | Never commit (already ignored) |
|
|
78
|
+
| --- | --- |
|
|
79
|
+
| `config.json`, `.env.example`, `api/`, `flows.json`, `baseline/` | `.env`, `report/`, `session.json` |
|
|
80
|
+
|
|
81
|
+
<details>
|
|
82
|
+
<summary><b>Set up with an older version?</b></summary>
|
|
83
|
+
|
|
84
|
+
Projects with `go-live-check.config.json`, `go-live-check.env`, `api/`, `go-live-baseline/` and `go-live-report/` at the root keep working. To move to the folder:
|
|
85
|
+
|
|
86
|
+
```bash
|
|
87
|
+
mkdir -p go-live-check
|
|
88
|
+
git mv go-live-check.config.json go-live-check/config.json
|
|
89
|
+
git mv go-live-check.env.example go-live-check/.env.example
|
|
90
|
+
git mv api go-live-check/api
|
|
91
|
+
git mv go-live-baseline go-live-check/baseline
|
|
92
|
+
mv go-live-check.env go-live-check/.env
|
|
93
|
+
printf '.env\nreport/\nsession.json\n' > go-live-check/.gitignore
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
In `go-live-check/config.json`, change `$schema` to `../node_modules/frontend-go-live-check/schema.json`. Remove the old `go-live-report/` folder and its `.gitignore` lines.
|
|
97
|
+
|
|
98
|
+
</details>
|
|
99
|
+
|
|
100
|
+
---
|
|
101
|
+
|
|
53
102
|
## Why
|
|
54
103
|
|
|
55
104
|
| Without it | With it |
|
|
@@ -99,7 +148,7 @@ npx frontend-go-live-check login
|
|
|
99
148
|
What happens:
|
|
100
149
|
|
|
101
150
|
- A normal browser window opens on your app. Sign in the way your users do (approve UAE PASS on your phone), wait for a signed-in page, then press Enter in the terminal.
|
|
102
|
-
- The session (cookies and browser storage) is saved in **`go-live-check
|
|
151
|
+
- The session (cookies and browser storage) is saved in **`go-live-check/session.json`**. Treat it like a password: Git ignores it, never share it.
|
|
103
152
|
- When it expires, the report says ***"The saved sign-in session has expired"*** (also when the app's API starts answering 401), and `doctor` tells you before you run. Run `login` again.
|
|
104
153
|
|
|
105
154
|
**Pipelines (`ciLogin`)**: a pipeline has no one to approve a sign-in, so it uses `ciLogin` instead of `login`. Pick one of these:
|
|
@@ -144,19 +193,22 @@ The report lists every sign-in method found (*email and password · Google · UA
|
|
|
144
193
|
|
|
145
194
|
| | Area | What is checked |
|
|
146
195
|
| :-: | --- | --- |
|
|
196
|
+
| ✅ | **Unit and end-to-end tests** | Runs **your own tests**: Vitest, Jest, Karma or `npm test` with code coverage (low coverage is reported), and your Playwright or Cypress tests against the production build |
|
|
197
|
+
| 🧭 | **User flows and business rules** | Your main journeys and business rules, written **without code** in `go-live-check/flows.json` (open, fill, click, see, check the API answer), on every screen size; a broken business rule blocks going live |
|
|
198
|
+
| 📝 | **Forms with valid data** | Every form is filled with valid test data and sent: it must save and tell the user (only on this computer or allowed test hosts) |
|
|
147
199
|
| 🧭 | **Functionality** | JavaScript errors, console errors, failed requests, broken links, images and anchors, blank pages, buttons covered by something else, unfinished text (`undefined`, `NaN`, `[object Object]`, translation keys, lorem ipsum, TODO), loading spinners that never stop, the production build, the "page not found" page |
|
|
148
200
|
| 🛟 | **Resilience** | Each page opened again with its API calls failing: does it crash, go blank, or tell the user? |
|
|
149
201
|
| 📱 | **Design and responsive layout** | Every page at every screen size: sideways scrolling, text that spills out of its box (a button too small for its label), text on top of other text, content cut off at the screen edge, text cut off inside its box, overlapping buttons, stretched or squashed images, tiny text on phones, right-to-left layout (Arabic, Hebrew…), fonts that fail to load, too many fonts and sizes |
|
|
150
|
-
| 🖼️ | **Visual changes** |
|
|
202
|
+
| 🖼️ | **Visual changes** | Every page compared with its approved look (the baseline): **Before**, **Now** and the changed areas side by side |
|
|
151
203
|
| ♿ | **Accessibility** | axe-core against WCAG 2.0 / 2.1 / 2.2 A and AA; keyboard-only use: visible focus, no traps, nothing that only a mouse can click; form field types |
|
|
152
204
|
| ⚡ | **Performance** | Size, JavaScript, requests, load time, LCP, layout shift and frozen-page time for every page, against budgets; Lighthouse as a phone and as a desktop |
|
|
153
205
|
| 🔌 | **API calls made by the pages** | Slow, very large, repeated, too many, uncompressed or uncached calls |
|
|
154
|
-
| 📈 | **Load** | 10 users
|
|
206
|
+
| 📈 | **Load** | Profiles: `light` (10 users, every run), `standard` (50 users for a minute, added gradually) and `stress` (adds users until the app slows down or fails: the **breaking point**) |
|
|
155
207
|
| 🔐 | **Sign-in and access** | Every sign-in method found (email, Google, Microsoft, Apple, UAE PASS, OpenID Connect) and its buttons; wrong password, unknown user, empty sign-in; a cancelled sign-in; signed-in pages and APIs opened without signing in; tokens in web storage; every form submitted empty |
|
|
156
|
-
| 🧪 | **API tests** | From your **Postman collection or OpenAPI/Swagger file**: every endpoint with valid and invalid data, without a token, with the wrong role, and with another user's records |
|
|
157
|
-
| 🛡️ | **Security** | Security headers, cookies, private files (`.env`, `.git`), source maps, secrets in the JavaScript or the source, passwords in addresses, outside scripts without integrity, `npm audit` |
|
|
208
|
+
| 🧪 | **API tests** | From your **Postman collection or OpenAPI/Swagger file**: every endpoint with valid and invalid data, without a token, with the wrong role, and with another user's records. Plus the **collection run in order with its own `pm.test` scripts**, the variables carried between requests (sign in → create → read → delete) |
|
|
209
|
+
| 🛡️ | **Security** | Security headers, cookies, CORS (which sites may read the API), the HTTPS certificate and TLS version, private files (`.env`, `.git`), source maps, secrets in the JavaScript or the source, passwords in addresses, outside scripts without integrity, `npm audit` |
|
|
158
210
|
| 🔎 | **SEO and sharing** | Titles, descriptions, headings, language, duplicate titles, favicon, link previews, robots.txt and sitemap.xml |
|
|
159
|
-
| 🧹 | **Code** | TypeScript errors, your
|
|
211
|
+
| 🧹 | **Code** | TypeScript errors, your ESLint rules (or your `lint` / `typecheck` scripts), leftover `console.log`, libraries installed but never used, libraries a major version behind, very long files, copied code |
|
|
160
212
|
|
|
161
213
|
The report's **What was checked** table says exactly what ran on your project, and why anything was skipped.
|
|
162
214
|
|
|
@@ -170,7 +222,7 @@ The report's **What was checked** table says exactly what ran on your project, a
|
|
|
170
222
|
|
|
171
223
|
| Step | What happens |
|
|
172
224
|
| :-: | --- |
|
|
173
|
-
| **1. Detect** | Reads `package.json`: the framework, the package manager, the sign-in libraries, and your
|
|
225
|
+
| **1. Detect** | Reads `package.json`: the framework, the package manager, the sign-in libraries, and your files in `go-live-check/` |
|
|
174
226
|
| **2. Build & start** | Builds the app and starts it **the way it runs in production**, plus any services you listed (a backend or a mock API) |
|
|
175
227
|
| **3. Sign in** | With the test account, the saved session (`login`) or a test token, so the signed-in pages are tested too |
|
|
176
228
|
| **4. Find pages** | Follows every link, reads your routes in the source code and your `sitemap.xml` |
|
|
@@ -180,6 +232,44 @@ The report's **What was checked** table says exactly what ran on your project, a
|
|
|
180
232
|
|
|
181
233
|
---
|
|
182
234
|
|
|
235
|
+
## User flows and business rules (no code)
|
|
236
|
+
|
|
237
|
+
The tool opens every page by itself, but only your team knows the journeys and the rules. Write them once in **`go-live-check/flows.json`**; every run checks them on desktop and phone, with a picture where a step fails.
|
|
238
|
+
|
|
239
|
+
```json
|
|
240
|
+
{
|
|
241
|
+
"flows": [
|
|
242
|
+
{
|
|
243
|
+
"name": "A citizen sends a new application",
|
|
244
|
+
"rule": true,
|
|
245
|
+
"steps": [
|
|
246
|
+
{ "open": "/applications/new" },
|
|
247
|
+
{ "select": { "Service": "Permit" } },
|
|
248
|
+
{ "fill": { "Description": "Permit for a small shop {unique}" } },
|
|
249
|
+
{ "click": "Submit application" },
|
|
250
|
+
{ "api": { "method": "POST", "path": "/api/applications", "status": 201, "body": { "status": "Submitted" } } },
|
|
251
|
+
{ "url": "/applications" },
|
|
252
|
+
{ "see": "Permit" }
|
|
253
|
+
]
|
|
254
|
+
}
|
|
255
|
+
]
|
|
256
|
+
}
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
| Step | What it does |
|
|
260
|
+
| --- | --- |
|
|
261
|
+
| `open` | Opens an address of the app |
|
|
262
|
+
| `fill`, `select`, `check` | Fills fields found by their label, placeholder or name (`css=…` works too). `"$NAME"` comes from `.env`; `{unique}` is unique to the run |
|
|
263
|
+
| `click`, `press` | Clicks a button or link by its text; presses a key |
|
|
264
|
+
| `see`, `notSee` | A text must (or must not) be on the page |
|
|
265
|
+
| `url` | The address must start with this |
|
|
266
|
+
| `api` | The page called this API, it answered this status, and its JSON answer has these values |
|
|
267
|
+
| `wait` | Waits a moment (ms) |
|
|
268
|
+
|
|
269
|
+
A flow is signed in with the test user unless `"signedIn": false`. **`"rule": true`** marks a business rule ("a new application is Submitted", "a citizen sees only their own applications"): if it fails, it is a blocker.
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
183
273
|
## Works with
|
|
184
274
|
|
|
185
275
|
**Next.js** · **React** (Vite, Create React App) · **Vue** · **Nuxt** · **Angular** · **Svelte / SvelteKit** · **Astro** · **Remix / React Router** · **Gatsby** · **Solid** · **Preact** · **Qwik** · **plain HTML**. Anything else, in any language, works with a start command or `--url`.
|
|
@@ -214,7 +304,8 @@ The framework and the package manager (npm, pnpm, yarn, bun) are detected. The a
|
|
|
214
304
|
|
|
215
305
|
The report has:
|
|
216
306
|
|
|
217
|
-
- the **verdict** and a **score per area** (click an area to
|
|
307
|
+
- when it was created, the **verdict** and a **score per area** (click an area to jump to it);
|
|
308
|
+
- every section opens and closes, with **Expand all** and **Collapse all**;
|
|
218
309
|
- **problems by type**: Functionality, Design, Accessibility, Performance, Sign-in, APIs, Security, SEO, Code, each with its score, worst problems first;
|
|
219
310
|
- the API results, the speed of every page, and the load test;
|
|
220
311
|
- screenshots of every page at every size, for the design review.
|
|
@@ -316,7 +407,7 @@ The short name `go-live-check` works too. After `init`, use `npm run go-live`, `
|
|
|
316
407
|
|
|
317
408
|
| Option | What it does |
|
|
318
409
|
| --- | --- |
|
|
319
|
-
| `--only pages,security` | Only these areas: `pages`, `lighthouse`, `auth`, `security`, `resilience`, `load`, `api`, `code` |
|
|
410
|
+
| `--only pages,security` | Only these areas: `pages`, `lighthouse`, `auth`, `flows`, `security`, `resilience`, `load`, `api`, `code`, `tests` |
|
|
320
411
|
| `--skip lighthouse,load` | Everything except these |
|
|
321
412
|
| `--api-only` | Only the API tests (backend projects) |
|
|
322
413
|
| `--api <file or URL>` | The Postman collection or OpenAPI/Swagger file (found automatically in the project) |
|
|
@@ -327,6 +418,7 @@ The short name `go-live-check` works too. After `init`, use `npm run go-live`, `
|
|
|
327
418
|
| `--no-lighthouse` · `--no-build` · `--no-export` | Skip Lighthouse · use the existing build · no PDF/Word |
|
|
328
419
|
| `--format pdf` | Only one of the documents |
|
|
329
420
|
| `--update-baseline` | Save the current look of every page as the new design baseline |
|
|
421
|
+
| `--load stress` | `light` (default) · `standard` (50 users for a minute) · `stress` (finds the breaking point) |
|
|
330
422
|
| `--fail-on major` | What fails the command: `blocker` (default) · `major` · `minor` · `never` |
|
|
331
423
|
| `--open` · `--out <folder>` · `--config <file>` · `--quiet` · `--ci` | Open the report · report folder · settings file · less output · pipeline mode |
|
|
332
424
|
|
|
@@ -336,18 +428,18 @@ The short name `go-live-check` works too. After `init`, use `npm run go-live`, `
|
|
|
336
428
|
|
|
337
429
|
## Settings
|
|
338
430
|
|
|
339
|
-
Everything is optional. `init` writes `go-live-check
|
|
431
|
+
Everything is optional. `init` writes `go-live-check/config.json`, and your editor autocompletes it through `$schema`.
|
|
340
432
|
|
|
341
433
|
```json
|
|
342
434
|
{
|
|
343
|
-
"$schema": "
|
|
435
|
+
"$schema": "../node_modules/frontend-go-live-check/schema.json",
|
|
344
436
|
"login": { "page": "/login", "username": "test.user", "password": "$GO_LIVE_PASSWORD" },
|
|
345
437
|
"services": [{ "command": "npm run api", "url": "http://localhost:4000/health" }],
|
|
346
438
|
"failOn": "blocker"
|
|
347
439
|
}
|
|
348
440
|
```
|
|
349
441
|
|
|
350
|
-
API tests need no settings when your files are in `api/` (see *API tests from Postman or OpenAPI* below). Passwords are written as `"$NAME"`. Put their values in `go-live-check
|
|
442
|
+
API tests need no settings when your files are in `go-live-check/api/` (see *API tests from Postman or OpenAPI* below). Passwords are written as `"$NAME"`. Put their values in `go-live-check/.env` (Git ignores it) or in your pipeline's secrets. They are replaced with `‹secret›` in every report.
|
|
351
443
|
|
|
352
444
|
<details>
|
|
353
445
|
<summary><b>🔐 Sign-in forms that need help</b></summary>
|
|
@@ -376,19 +468,16 @@ An external single sign-on page usually can't be automated. Point `login` at a t
|
|
|
376
468
|
<details>
|
|
377
469
|
<summary><b>🧪 API tests from Postman or OpenAPI</b></summary>
|
|
378
470
|
|
|
379
|
-
Put your API description in
|
|
471
|
+
Put your API description in **`go-live-check/api/`**, with **exactly these names**:
|
|
380
472
|
|
|
381
473
|
```text
|
|
382
|
-
|
|
383
|
-
├──
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
│ └── openapi.json ← or/and the OpenAPI / Swagger file (openapi.yaml works too)
|
|
387
|
-
├── go-live-check.config.json
|
|
388
|
-
└── package.json
|
|
474
|
+
go-live-check/api/
|
|
475
|
+
├── postman_collection.json ← the Postman collection (v2.1)
|
|
476
|
+
├── postman_environment.json ← optional: its environment ({{baseUrl}} and other variables)
|
|
477
|
+
└── openapi.json ← or/and the OpenAPI / Swagger file (openapi.yaml works too)
|
|
389
478
|
```
|
|
390
479
|
|
|
391
|
-
That's all: no settings are needed. Postman export names (`My API.postman_collection.json`) need renaming to `postman_collection.json`. If both a Postman collection and an OpenAPI file are there, they are combined: OpenAPI gives the rules, Postman the examples. `init` creates `api/README.md` with these instructions. `frontend-go-live-check doctor` shows what it found.
|
|
480
|
+
That's all: no settings are needed. Postman export names (`My API.postman_collection.json`) need renaming to `postman_collection.json`. If both a Postman collection and an OpenAPI file are there, they are combined: OpenAPI gives the rules, Postman the examples. `init` creates `go-live-check/api/README.md` with these instructions. `frontend-go-live-check doctor` shows what it found.
|
|
392
481
|
|
|
393
482
|
Never put real passwords or tokens in these files: use `$NAMES` (see below).
|
|
394
483
|
|
|
@@ -416,7 +505,7 @@ To test roles and ownership, add test users. Include a **second user of the same
|
|
|
416
505
|
<details>
|
|
417
506
|
<summary><b>🖼️ Visual changes</b></summary>
|
|
418
507
|
|
|
419
|
-
The first run saves a picture of every page at every size in `go-live-baseline/`. Commit that folder. Later runs report pages that look different, with the changed areas in red.
|
|
508
|
+
The first run saves a picture of every page at every size in `go-live-check/baseline/`. Commit that folder. Later runs report pages that look different, with the changed areas in red.
|
|
420
509
|
|
|
421
510
|
After an intended design change, save the new look:
|
|
422
511
|
|
|
@@ -439,7 +528,11 @@ Hide parts that change on their own (clocks, live data) with `"visualMask": [".c
|
|
|
439
528
|
| `services` | Commands started first (a backend, a mock API), each ready when its `url` answers |
|
|
440
529
|
| `build`, `start`, `url` | `false` or your own build command · your own start command (`{port}` / `$PORT`) · check a running site |
|
|
441
530
|
| `budgets` | `pageKB` 3000 · `jsKB` 1000 · `requests` 120 · `loadMs` 4000 · `apiMs` 1000 · `apiCalls` 30 |
|
|
442
|
-
| `load` | `{ "
|
|
531
|
+
| `load` | `{ "profile": "light" | "standard" | "stress" }` or your own `users`, `seconds`, `rampSeconds`, `hosts`; or `false` (GET only; this computer or listed hosts) |
|
|
532
|
+
| `tests` | `{ "coverage": 60, "unitCommand": "…", "e2eCommand": "…" }`, or `false` to skip your own tests |
|
|
533
|
+
| `flows` | User journeys and business rules (or in `go-live-check/flows.json`) |
|
|
534
|
+
| `formFill` | `{ "hosts": ["test.example.com"] }` to also fill and send forms on a test host, or `false` |
|
|
535
|
+
| `api.variables` | Values for `{{variables}}` in the Postman collection, e.g. `{ "password": "$GO_LIVE_PASSWORD" }` |
|
|
443
536
|
| `keyboard`, `resilience`, `visual`, `evidence`, `formChecks`, `lighthouse`, `discoverRoutes` | All on by default; `false` turns one off |
|
|
444
537
|
| `visualThreshold`, `visualMask`, `baselineDir` | How much may change (0.1%); parts to hide; where the baseline lives |
|
|
445
538
|
| `report` | `organisation`, `classification` (default *Internal*), `preparedFor`, `approvers`: shown in the PDF and Word |
|
|
@@ -455,7 +548,7 @@ Hide parts that change on their own (clocks, live data) with `"visualMask": [".c
|
|
|
455
548
|
## Safety and privacy
|
|
456
549
|
|
|
457
550
|
- **Everything runs on your machine** or your own pipeline. Nothing is sent anywhere except to the app being tested.
|
|
458
|
-
- **Test passwords** come from `go-live-check
|
|
551
|
+
- **Test passwords** come from `go-live-check/.env` or pipeline secrets, and never appear in a report or log.
|
|
459
552
|
- **Use test accounts on a test environment.** Browser checks only read pages and submit forms empty.
|
|
460
553
|
- **API writes and the load test** run only against this computer or the hosts you list. Every record the tests create is deleted afterwards.
|
|
461
554
|
- **Closed networks.** Point `PLAYWRIGHT_DOWNLOAD_HOST` at your mirror, or `GO_LIVE_CHROMIUM` at an existing Chromium.
|
|
@@ -500,7 +593,7 @@ No other services: nothing is uploaded, and no account is needed.
|
|
|
500
593
|
<details>
|
|
501
594
|
<summary><b>Does it replace unit and end-to-end tests?</b></summary>
|
|
502
595
|
|
|
503
|
-
|
|
596
|
+
It runs them. Your own unit tests (with coverage) and your Playwright or Cypress tests are part of every run, and their results are in the same report and the same verdict. Your journeys and business rules can also be written as flows, without code. Writing the unit tests themselves is still your team's job: only you know what each function must do.
|
|
504
597
|
|
|
505
598
|
</details>
|
|
506
599
|
|
|
@@ -521,10 +614,10 @@ Security headers, compression and caching usually come from your web server or C
|
|
|
521
614
|
<details>
|
|
522
615
|
<summary><b>What still needs a person?</b></summary>
|
|
523
616
|
|
|
524
|
-
- whether the design matches what was intended (the screenshots make this quick);
|
|
525
|
-
- business rules;
|
|
526
|
-
- a
|
|
527
|
-
- a penetration test.
|
|
617
|
+
- whether the design matches what was intended (the screenshots and the visual comparison make this quick);
|
|
618
|
+
- writing the flows and unit tests for your business rules (the tool runs them every time);
|
|
619
|
+
- a load test from proper servers for a very large launch (the `stress` profile finds the breaking point on one machine);
|
|
620
|
+
- a penetration test by a security specialist before a big launch.
|
|
528
621
|
|
|
529
622
|
</details>
|
|
530
623
|
|
|
@@ -534,7 +627,7 @@ Security headers, compression and caching usually come from your web server or C
|
|
|
534
627
|
| You see | Fix |
|
|
535
628
|
| --- | --- |
|
|
536
629
|
| `Executable doesn't exist` | `npx playwright install chromium` |
|
|
537
|
-
| `Not set: GO_LIVE_PASSWORD` | Copy `go-live-check
|
|
630
|
+
| `Not set: GO_LIVE_PASSWORD` | Copy `go-live-check/.env.example` to `go-live-check/.env` and fill it in |
|
|
538
631
|
| `login-failed` | Check `login`; name the fields (`usernameField`, `passwordField`, `submit`) if the form is unusual |
|
|
539
632
|
| *Signed-in pages were not tested* | Set `login`, or run `npx frontend-go-live-check login` (Google, UAE PASS…) |
|
|
540
633
|
| *The saved sign-in session has expired* | Run `npx frontend-go-live-check login` again |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "frontend-go-live-check",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.6.0",
|
|
4
4
|
"description": "Is your frontend ready to go live? One command tests any web frontend (React, Next.js, Vue, Angular, Svelte, plain HTML…): pages, responsive design, accessibility, keyboard, performance and load, API calls, security, SEO, sign-in and APIs from Postman/OpenAPI. Report with evidence, PDF and Word, and a pipeline gate that approves or rejects the merge.",
|
|
5
5
|
"homepage": "https://www.npmjs.com/package/frontend-go-live-check",
|
|
6
6
|
"repository": {
|
package/schema.json
CHANGED
|
@@ -154,7 +154,7 @@
|
|
|
154
154
|
},
|
|
155
155
|
"password": {
|
|
156
156
|
"type": "string",
|
|
157
|
-
"description": "Use \"$NAME\" and put NAME in go-live-check
|
|
157
|
+
"description": "Use \"$NAME\" and put NAME in go-live-check/.env."
|
|
158
158
|
},
|
|
159
159
|
"usernameField": {
|
|
160
160
|
"type": "string",
|
|
@@ -169,7 +169,7 @@
|
|
|
169
169
|
},
|
|
170
170
|
"fields": {
|
|
171
171
|
"type": "object",
|
|
172
|
-
"description": "Other fields to fill: label
|
|
172
|
+
"description": "Other fields to fill: label → value."
|
|
173
173
|
},
|
|
174
174
|
"expect": {
|
|
175
175
|
"type": "string",
|
|
@@ -181,7 +181,7 @@
|
|
|
181
181
|
"session",
|
|
182
182
|
"token"
|
|
183
183
|
],
|
|
184
|
-
"description": "form = fill the email/password form
|
|
184
|
+
"description": "form = fill the email/password form · session = reuse the session saved by 'frontend-go-live-check login' · token = a test token. Default: form when username/password are set, token when token is set, otherwise session."
|
|
185
185
|
},
|
|
186
186
|
"token": {
|
|
187
187
|
"type": "object",
|
|
@@ -193,24 +193,24 @@
|
|
|
193
193
|
},
|
|
194
194
|
"cookies": {
|
|
195
195
|
"type": "object",
|
|
196
|
-
"description": "Cookie name
|
|
196
|
+
"description": "Cookie name → value."
|
|
197
197
|
},
|
|
198
198
|
"localStorage": {
|
|
199
199
|
"type": "object",
|
|
200
|
-
"description": "Key
|
|
200
|
+
"description": "Key → value, set before the app loads."
|
|
201
201
|
},
|
|
202
202
|
"sessionStorage": {
|
|
203
203
|
"type": "object",
|
|
204
|
-
"description": "Key
|
|
204
|
+
"description": "Key → value, set before the app loads."
|
|
205
205
|
}
|
|
206
206
|
}
|
|
207
207
|
},
|
|
208
208
|
"sessionFile": {
|
|
209
209
|
"type": "string",
|
|
210
|
-
"description": "Where the saved session is kept. Default go-live-check
|
|
210
|
+
"description": "Where the saved session is kept. Default go-live-check/session.json (never commit it)."
|
|
211
211
|
}
|
|
212
212
|
},
|
|
213
|
-
"description": "How the tool signs in. Email/password: page + username + password. Google, Microsoft, Apple, UAE PASS
|
|
213
|
+
"description": "How the tool signs in. Email/password: page + username + password. Google, Microsoft, Apple, UAE PASS…: \"method\": \"session\" and run frontend-go-live-check login once. Pipelines: see ciLogin."
|
|
214
214
|
},
|
|
215
215
|
"lighthouse": {
|
|
216
216
|
"type": "boolean"
|
|
@@ -358,6 +358,13 @@
|
|
|
358
358
|
},
|
|
359
359
|
"seed": {
|
|
360
360
|
"type": "integer"
|
|
361
|
+
},
|
|
362
|
+
"variables": {
|
|
363
|
+
"type": "object",
|
|
364
|
+
"additionalProperties": {
|
|
365
|
+
"type": "string"
|
|
366
|
+
},
|
|
367
|
+
"description": "Values for {{variables}} in the Postman collection, e.g. { \"password\": \"$GO_LIVE_PASSWORD\" }."
|
|
361
368
|
}
|
|
362
369
|
}
|
|
363
370
|
}
|
|
@@ -422,6 +429,227 @@
|
|
|
422
429
|
"ciLogin": {
|
|
423
430
|
"$ref": "#/properties/login",
|
|
424
431
|
"description": "Used instead of \"login\" in pipelines (no one there to approve a Google or UAE PASS sign-in): a test email/password on the test environment, or a test token from the pipeline's secrets."
|
|
432
|
+
},
|
|
433
|
+
"load": {
|
|
434
|
+
"description": "The load test: false, or a profile and/or your own numbers. GET requests only, on this computer or the hosts listed.",
|
|
435
|
+
"oneOf": [
|
|
436
|
+
{
|
|
437
|
+
"const": false
|
|
438
|
+
},
|
|
439
|
+
{
|
|
440
|
+
"type": "object",
|
|
441
|
+
"additionalProperties": false,
|
|
442
|
+
"properties": {
|
|
443
|
+
"profile": {
|
|
444
|
+
"enum": [
|
|
445
|
+
"light",
|
|
446
|
+
"standard",
|
|
447
|
+
"stress"
|
|
448
|
+
],
|
|
449
|
+
"description": "light: 10 users for 10 s (default) · standard: 50 users for 60 s, added over 15 s · stress: adds 10 users every 10 s until the app gets slow or fails (the breaking point)"
|
|
450
|
+
},
|
|
451
|
+
"users": {
|
|
452
|
+
"type": "integer",
|
|
453
|
+
"minimum": 1
|
|
454
|
+
},
|
|
455
|
+
"seconds": {
|
|
456
|
+
"type": "integer",
|
|
457
|
+
"minimum": 1
|
|
458
|
+
},
|
|
459
|
+
"rampSeconds": {
|
|
460
|
+
"type": "integer",
|
|
461
|
+
"minimum": 0
|
|
462
|
+
},
|
|
463
|
+
"step": {
|
|
464
|
+
"type": "integer",
|
|
465
|
+
"minimum": 1,
|
|
466
|
+
"description": "stress: users added per step"
|
|
467
|
+
},
|
|
468
|
+
"maxTargets": {
|
|
469
|
+
"type": "integer",
|
|
470
|
+
"minimum": 1
|
|
471
|
+
},
|
|
472
|
+
"hosts": {
|
|
473
|
+
"type": "array",
|
|
474
|
+
"items": {
|
|
475
|
+
"type": "string"
|
|
476
|
+
},
|
|
477
|
+
"description": "Other hosts the load test may call (test environments only)."
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
]
|
|
482
|
+
},
|
|
483
|
+
"tests": {
|
|
484
|
+
"description": "The project's own unit and end-to-end tests. false turns them off.",
|
|
485
|
+
"oneOf": [
|
|
486
|
+
{
|
|
487
|
+
"const": false
|
|
488
|
+
},
|
|
489
|
+
{
|
|
490
|
+
"type": "object",
|
|
491
|
+
"additionalProperties": false,
|
|
492
|
+
"properties": {
|
|
493
|
+
"unit": {
|
|
494
|
+
"type": "boolean",
|
|
495
|
+
"default": true
|
|
496
|
+
},
|
|
497
|
+
"e2e": {
|
|
498
|
+
"type": "boolean",
|
|
499
|
+
"default": true
|
|
500
|
+
},
|
|
501
|
+
"coverage": {
|
|
502
|
+
"type": "number",
|
|
503
|
+
"minimum": 0,
|
|
504
|
+
"maximum": 100,
|
|
505
|
+
"default": 60,
|
|
506
|
+
"description": "Minimum share of code lines covered by the unit tests (%)."
|
|
507
|
+
},
|
|
508
|
+
"unitCommand": {
|
|
509
|
+
"type": "string",
|
|
510
|
+
"description": "Your own command for the unit tests (instead of Vitest/Jest/Karma)."
|
|
511
|
+
},
|
|
512
|
+
"e2eCommand": {
|
|
513
|
+
"type": "string",
|
|
514
|
+
"description": "Your own command for the end-to-end tests. BASE_URL points at the app."
|
|
515
|
+
}
|
|
516
|
+
}
|
|
517
|
+
}
|
|
518
|
+
]
|
|
519
|
+
},
|
|
520
|
+
"flows": {
|
|
521
|
+
"description": "User journeys and business rules, written without code (they can also be in go-live-check/flows.json).",
|
|
522
|
+
"type": "array",
|
|
523
|
+
"items": {
|
|
524
|
+
"type": "object",
|
|
525
|
+
"required": [
|
|
526
|
+
"name",
|
|
527
|
+
"steps"
|
|
528
|
+
],
|
|
529
|
+
"properties": {
|
|
530
|
+
"name": {
|
|
531
|
+
"type": "string"
|
|
532
|
+
},
|
|
533
|
+
"rule": {
|
|
534
|
+
"type": "boolean",
|
|
535
|
+
"description": "A business rule: if it fails, it blocks going live."
|
|
536
|
+
},
|
|
537
|
+
"signedIn": {
|
|
538
|
+
"type": "boolean",
|
|
539
|
+
"default": true
|
|
540
|
+
},
|
|
541
|
+
"viewports": {
|
|
542
|
+
"type": "array",
|
|
543
|
+
"items": {
|
|
544
|
+
"type": "string"
|
|
545
|
+
}
|
|
546
|
+
},
|
|
547
|
+
"severity": {
|
|
548
|
+
"enum": [
|
|
549
|
+
"blocker",
|
|
550
|
+
"major",
|
|
551
|
+
"minor",
|
|
552
|
+
"info"
|
|
553
|
+
]
|
|
554
|
+
},
|
|
555
|
+
"steps": {
|
|
556
|
+
"type": "array",
|
|
557
|
+
"items": {
|
|
558
|
+
"type": "object",
|
|
559
|
+
"minProperties": 1,
|
|
560
|
+
"maxProperties": 1,
|
|
561
|
+
"properties": {
|
|
562
|
+
"open": {
|
|
563
|
+
"type": "string",
|
|
564
|
+
"description": "Open this address, e.g. /applications"
|
|
565
|
+
},
|
|
566
|
+
"fill": {
|
|
567
|
+
"type": "object",
|
|
568
|
+
"additionalProperties": {
|
|
569
|
+
"type": "string"
|
|
570
|
+
},
|
|
571
|
+
"description": "Field label, placeholder or name → value. \"$NAME\" comes from .env; {unique} is unique to the run."
|
|
572
|
+
},
|
|
573
|
+
"select": {
|
|
574
|
+
"type": "object",
|
|
575
|
+
"additionalProperties": {
|
|
576
|
+
"type": "string"
|
|
577
|
+
}
|
|
578
|
+
},
|
|
579
|
+
"check": {
|
|
580
|
+
"type": "string"
|
|
581
|
+
},
|
|
582
|
+
"click": {
|
|
583
|
+
"type": "string",
|
|
584
|
+
"description": "Button or link text (or css=selector)."
|
|
585
|
+
},
|
|
586
|
+
"press": {
|
|
587
|
+
"type": "string"
|
|
588
|
+
},
|
|
589
|
+
"see": {
|
|
590
|
+
"type": "string"
|
|
591
|
+
},
|
|
592
|
+
"notSee": {
|
|
593
|
+
"type": "string"
|
|
594
|
+
},
|
|
595
|
+
"url": {
|
|
596
|
+
"type": "string",
|
|
597
|
+
"description": "The address must start with this."
|
|
598
|
+
},
|
|
599
|
+
"api": {
|
|
600
|
+
"type": "object",
|
|
601
|
+
"required": [
|
|
602
|
+
"path"
|
|
603
|
+
],
|
|
604
|
+
"properties": {
|
|
605
|
+
"method": {
|
|
606
|
+
"type": "string"
|
|
607
|
+
},
|
|
608
|
+
"path": {
|
|
609
|
+
"type": "string",
|
|
610
|
+
"description": "e.g. /api/applications or /api/applications/:id"
|
|
611
|
+
},
|
|
612
|
+
"status": {
|
|
613
|
+
"type": "integer"
|
|
614
|
+
},
|
|
615
|
+
"body": {
|
|
616
|
+
"type": "object",
|
|
617
|
+
"description": "Values the JSON answer must have."
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
},
|
|
621
|
+
"wait": {
|
|
622
|
+
"type": "integer"
|
|
623
|
+
}
|
|
624
|
+
}
|
|
625
|
+
}
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
}
|
|
629
|
+
},
|
|
630
|
+
"formFill": {
|
|
631
|
+
"description": "Fill every form with valid test data and send it. Writes data: only on this computer or the hosts listed. false turns it off.",
|
|
632
|
+
"oneOf": [
|
|
633
|
+
{
|
|
634
|
+
"const": false
|
|
635
|
+
},
|
|
636
|
+
{
|
|
637
|
+
"type": "object",
|
|
638
|
+
"additionalProperties": false,
|
|
639
|
+
"properties": {
|
|
640
|
+
"hosts": {
|
|
641
|
+
"type": "array",
|
|
642
|
+
"items": {
|
|
643
|
+
"type": "string"
|
|
644
|
+
}
|
|
645
|
+
},
|
|
646
|
+
"max": {
|
|
647
|
+
"type": "integer",
|
|
648
|
+
"minimum": 1
|
|
649
|
+
}
|
|
650
|
+
}
|
|
651
|
+
}
|
|
652
|
+
]
|
|
425
653
|
}
|
|
426
654
|
}
|
|
427
655
|
}
|
package/src/api/model.mjs
CHANGED
|
@@ -242,6 +242,6 @@ export async function loadApiMap(api, dir) {
|
|
|
242
242
|
}
|
|
243
243
|
}
|
|
244
244
|
const baseUrl = sources.find((s) => s.baseUrl)?.baseUrl;
|
|
245
|
-
if (!sources.length) notes.push('No API file given: set "api": { "file": "postman_collection.json" } (or "openapi") in go-live-check
|
|
245
|
+
if (!sources.length) notes.push('No API file given: set "api": { "file": "postman_collection.json" } (or "openapi") in go-live-check/config.json, or put the file in go-live-check/api/, or --api <file>.');
|
|
246
246
|
return { endpoints: [...map.values()], baseUrl, basePath: sources.find((s) => s.basePath)?.basePath, title: sources.find((s) => s.title)?.title, sources: sources.map((s) => s.kind), notes };
|
|
247
247
|
}
|