jourilo 1.2.0 → 1.3.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/README.md +13 -13
- package/package.json +1 -1
- package/plugin/.claude-plugin/plugin.json +1 -1
- package/plugin/dist/jourilo.mjs +3032 -888
- package/plugin/skills/jourilo/references/cli.md +221 -19
- package/schemas/run.schema.json +111 -2
|
@@ -8,7 +8,13 @@ Every command prints human-readable text, or JSON with `--json`. Errors go to st
|
|
|
8
8
|
6 stopped early by SIGINT/SIGTERM or `--max-duration` (a partial run is still written; a second signal exits 130).
|
|
9
9
|
|
|
10
10
|
Global options: `--json`, `--workspace DIR` (default `.jourilo`, or `JOURILO_WORKSPACE`), `--quiet`. With `--json`,
|
|
11
|
-
progress lines on stderr are JSON too: `{"type":"progress","message":"…","at":"<ISO time>"}`.
|
|
11
|
+
progress lines on stderr are JSON too: `{"type":"progress","message":"…","at":"<ISO time>"}`. Lines from the audit
|
|
12
|
+
pipeline also carry `phase` (launch, discover, setup, capture, metrics, forms or report; `rules` is reserved and not
|
|
13
|
+
emitted yet) and, where known exactly, `done`, `total`, `url` and `viewport`. `done` counts the steps of that phase
|
|
14
|
+
finished before this step started, so the last line of a phase has `done` = `total` − 1; the phase is over when the
|
|
15
|
+
next phase's first line arrives or the run ends. `url` is redacted like the message, and the `message` text is the
|
|
16
|
+
same as the plain line (see docs/RUN-FORMAT.md). `--workspace` is also the output directory: every run is written
|
|
17
|
+
to `DIR/runs/<id>/` (there is no separate `--output-dir`).
|
|
12
18
|
|
|
13
19
|
## Understand
|
|
14
20
|
|
|
@@ -17,14 +23,36 @@ progress lines on stderr are JSON too: `{"type":"progress","message":"…","at":
|
|
|
17
23
|
Product intelligence: map a repository (frameworks, routes, design system, i18n, auth, analytics) or a website (pages, conversion points, services).
|
|
18
24
|
|
|
19
25
|
```
|
|
20
|
-
jourilo discover <path|url> [--pages 10] [--ignore-robots] [--allow-private]
|
|
26
|
+
jourilo discover <path|url> [--pages 10] [--ignore-robots] [--allow-private] [--deny-local]
|
|
21
27
|
```
|
|
22
28
|
|
|
23
29
|
```
|
|
24
30
|
Options:
|
|
25
|
-
--pages N
|
|
26
|
-
--ignore-robots
|
|
27
|
-
--allow-private
|
|
31
|
+
--pages N Pages to read when mapping a website (default 10)
|
|
32
|
+
--ignore-robots Ignore robots.txt (only for sites you own or are authorized to test)
|
|
33
|
+
--allow-private Allow private-network hosts (10.x, 192.168.x, ...)
|
|
34
|
+
--deny-local Refuse local targets (localhost, 127.0.0.1, [::1], *.localhost, *.test) (exit 3); a redirect or request to one is blocked by the network guard and listed in the limitations;
|
|
35
|
+
JOURILO_DENY_LOCAL=1 does the same
|
|
36
|
+
--proxy URL Chain to an upstream HTTP proxy (http://[user:password@]host:port) behind the network guard;
|
|
37
|
+
default HTTPS_PROXY / HTTP_PROXY (either case; prefer the variable for credentials, argv shows
|
|
38
|
+
in ps). NO_PROXY is decided per destination host (NO_PROXY=* = no proxy). The guard resolves and
|
|
39
|
+
checks every destination itself, then tunnels to the checked address (CONNECT ip:443, and ip:80
|
|
40
|
+
for plain HTTP; a proxy that refuses port 80 fails those requests: give an https:// target);
|
|
41
|
+
loopback connects directly. The run records the proxy without its credentials
|
|
42
|
+
--allow-hosts LIST Only these hosts may be reached (comma-separated or repeated; *.example.com = its subdomains);
|
|
43
|
+
the target's own host is always allowed. Other hosts are refused and listed in the limitations
|
|
44
|
+
--block-hosts LIST Refuse these hosts (e.g. *.tracker.example); refused requests are listed in the limitations
|
|
45
|
+
--user-agent UA Send this User-Agent (also navigator.userAgent) instead of the browser's own; recorded in the run
|
|
46
|
+
--extra-header H Add a request header "Name: value" (repeatable), sent only to the target's origin, never
|
|
47
|
+
to other hosts: Jourilo makes those requests itself, so the headers cannot follow a redirect
|
|
48
|
+
elsewhere (a redirect is followed without them). The run records the names, never the values
|
|
49
|
+
--ignore-https-errors
|
|
50
|
+
Accept invalid or self-signed certificates in the browser (test environments only); the network
|
|
51
|
+
guard still checks every destination, and the run lists it in the limitations
|
|
52
|
+
--chromium-sandbox
|
|
53
|
+
Keep Chromium's own process sandbox (Playwright disables it by default); JOURILO_CHROMIUM_SANDBOX=1
|
|
54
|
+
does the same. Chromium, Chrome and Edge only (a usage error with Firefox or WebKit). Fails to launch
|
|
55
|
+
where the system denies the sandbox (containers, some Linux CI kernels)
|
|
28
56
|
```
|
|
29
57
|
|
|
30
58
|
## Audit
|
|
@@ -34,12 +62,12 @@ Options:
|
|
|
34
62
|
Audit a website URL or a static build directory in a real browser (accessibility, UX, responsive, performance, reliability, conversion).
|
|
35
63
|
|
|
36
64
|
```
|
|
37
|
-
jourilo audit <url|dir> [--pages 6] [--viewports desktop,mobile] [--url /path ...] [--repo .] [--fail-on serious]
|
|
65
|
+
jourilo audit <url|dir> [--pages 6] [--viewports desktop,mobile] [--url /path ...] [--repo .] [--fail-on serious] [--budget LCP=2000]
|
|
38
66
|
```
|
|
39
67
|
|
|
40
68
|
```
|
|
41
69
|
Options:
|
|
42
|
-
--pages N Pages to audit after discovery (default 6; 1 = only the target)
|
|
70
|
+
--pages N Pages to audit after discovery (default 6; 1 = only the target; 0 is a usage error)
|
|
43
71
|
--depth N Link depth for discovery (default 3)
|
|
44
72
|
--url PATH Audit exactly these paths/URLs on the target origin (repeatable; skips discovery)
|
|
45
73
|
--include PATH Add pages to discovery (repeatable)
|
|
@@ -48,6 +76,8 @@ Options:
|
|
|
48
76
|
--headed Show the browser window instead of running headless
|
|
49
77
|
--locale TAG Browser locale for every page (e.g. tr-TR); sets Accept-Language and navigator.language
|
|
50
78
|
--timeout SECS Per-page navigation timeout in seconds (default 30)
|
|
79
|
+
--wait-for SELECTOR Capture each page only once this element is visible (client-rendered pages); if it never appears within
|
|
80
|
+
--timeout the page is still audited, with a limitation. Each capture records how it loaded
|
|
51
81
|
--throttle Simulate a mid-range phone network and 4x CPU slowdown (Chromium)
|
|
52
82
|
--runs N Visits per page and viewport for lab metrics; reports the median and range (default 1, max 9)
|
|
53
83
|
--no-keyboard Skip the keyboard-only walk
|
|
@@ -61,6 +91,28 @@ Options:
|
|
|
61
91
|
--brand SLUG Markilo brand to check design consistency against (default: master brand)
|
|
62
92
|
--ignore-robots Ignore robots.txt (only for sites you own or are authorized to test)
|
|
63
93
|
--allow-private Allow private-network hosts (10.x, 192.168.x, ...)
|
|
94
|
+
--deny-local Refuse local targets (localhost, 127.0.0.1, [::1], *.localhost, *.test) (exit 3); a redirect or request to one is blocked by the network guard and listed in the limitations;
|
|
95
|
+
JOURILO_DENY_LOCAL=1 does the same. Not available with --browser webkit (exit 3). For hosted integrations; a directory target is still served
|
|
96
|
+
--proxy URL Chain to an upstream HTTP proxy (http://[user:password@]host:port) behind the network guard;
|
|
97
|
+
default HTTPS_PROXY / HTTP_PROXY (either case; prefer the variable for credentials, argv shows
|
|
98
|
+
in ps). NO_PROXY is decided per destination host (NO_PROXY=* = no proxy). The guard resolves and
|
|
99
|
+
checks every destination itself, then tunnels to the checked address (CONNECT ip:443, and ip:80
|
|
100
|
+
for plain HTTP; a proxy that refuses port 80 fails those requests: give an https:// target);
|
|
101
|
+
loopback connects directly. The run records the proxy without its credentials
|
|
102
|
+
--allow-hosts LIST Only these hosts may be reached (comma-separated or repeated; *.example.com = its subdomains);
|
|
103
|
+
the target's own host is always allowed. Other hosts are refused and listed in the limitations
|
|
104
|
+
--block-hosts LIST Refuse these hosts (e.g. *.tracker.example); refused requests are listed in the limitations
|
|
105
|
+
--user-agent UA Send this User-Agent (also navigator.userAgent) instead of the browser's own; recorded in the run
|
|
106
|
+
--extra-header H Add a request header "Name: value" (repeatable), sent only to the target's origin, never
|
|
107
|
+
to other hosts: Jourilo makes those requests itself, so the headers cannot follow a redirect
|
|
108
|
+
elsewhere (a redirect is followed without them). The run records the names, never the values
|
|
109
|
+
--ignore-https-errors
|
|
110
|
+
Accept invalid or self-signed certificates in the browser (test environments only); the network
|
|
111
|
+
guard still checks every destination, and the run lists it in the limitations
|
|
112
|
+
--chromium-sandbox
|
|
113
|
+
Keep Chromium's own process sandbox (Playwright disables it by default); JOURILO_CHROMIUM_SANDBOX=1
|
|
114
|
+
does the same. Chromium, Chrome and Edge only (a usage error with Firefox or WebKit). Fails to launch
|
|
115
|
+
where the system denies the sandbox (containers, some Linux CI kernels)
|
|
64
116
|
--no-forms Skip the form validation probe
|
|
65
117
|
(by default, on local hosts, an empty submission is simulated: nothing that sends data
|
|
66
118
|
leaves the browser, so no database is written; server-side feedback is reported as untested)
|
|
@@ -69,10 +121,15 @@ Options:
|
|
|
69
121
|
also lets a --setup-journey submit forms
|
|
70
122
|
--sarif Also write report.sarif for code scanning
|
|
71
123
|
--fail-on SEVERITY Exit 1 if a defect at or above this severity exists (CI gate)
|
|
124
|
+
--budget LIST Exit 1 when a lab metric exceeds its limit, e.g. LCP=2000,CLS=0.05,TBT=300 (LCP, CLS, INP, FCP,
|
|
125
|
+
TTFB, TBT; ms, CLS unitless). Each capture's median is compared and the worst capture decides;
|
|
126
|
+
a metric no page measured (INP) is reported as not measured, not as a pass. Combines with --fail-on
|
|
72
127
|
--evidence MODE full (default) or minimal: keep first screens and only the full-page screenshots findings need; JPEG quality 55
|
|
73
|
-
--run-id ID Use this run id instead of a generated one (1-64 of A-Z a-z 0-9 _ -); refused
|
|
74
|
-
|
|
75
|
-
|
|
128
|
+
--run-id ID Use this run id instead of a generated one (1-64 of A-Z a-z 0-9 _ -); refused (exit 2) if its
|
|
129
|
+
directory exists, even without a run.json (left by a crashed run)
|
|
130
|
+
--max-duration SECS Stop after this many seconds (1 to 86400) and write a partial run (exit 6), as SIGINT/SIGTERM do;
|
|
131
|
+
the page in progress gets up to 3 s to finish, then it is left out; a second signal quits at
|
|
132
|
+
once (exit 130) after one line on stderr (STOPPED_TWICE with --json)
|
|
76
133
|
```
|
|
77
134
|
|
|
78
135
|
### `jourilo accessibility`
|
|
@@ -85,7 +142,7 @@ jourilo accessibility <url|dir> [audit options]
|
|
|
85
142
|
|
|
86
143
|
```
|
|
87
144
|
Options:
|
|
88
|
-
--pages N Pages to audit after discovery (default 6; 1 = only the target)
|
|
145
|
+
--pages N Pages to audit after discovery (default 6; 1 = only the target; 0 is a usage error)
|
|
89
146
|
--depth N Link depth for discovery (default 3)
|
|
90
147
|
--url PATH Audit exactly these paths/URLs on the target origin (repeatable; skips discovery)
|
|
91
148
|
--include PATH Add pages to discovery (repeatable)
|
|
@@ -94,6 +151,8 @@ Options:
|
|
|
94
151
|
--headed Show the browser window instead of running headless
|
|
95
152
|
--locale TAG Browser locale for every page (e.g. tr-TR); sets Accept-Language and navigator.language
|
|
96
153
|
--timeout SECS Per-page navigation timeout in seconds (default 30)
|
|
154
|
+
--wait-for SELECTOR Capture each page only once this element is visible (client-rendered pages); if it never appears within
|
|
155
|
+
--timeout the page is still audited, with a limitation. Each capture records how it loaded
|
|
97
156
|
--throttle Simulate a mid-range phone network and 4x CPU slowdown (Chromium)
|
|
98
157
|
--runs N Visits per page and viewport for lab metrics; reports the median and range (default 1, max 9)
|
|
99
158
|
--no-keyboard Skip the keyboard-only walk
|
|
@@ -107,6 +166,28 @@ Options:
|
|
|
107
166
|
--brand SLUG Markilo brand to check design consistency against (default: master brand)
|
|
108
167
|
--ignore-robots Ignore robots.txt (only for sites you own or are authorized to test)
|
|
109
168
|
--allow-private Allow private-network hosts (10.x, 192.168.x, ...)
|
|
169
|
+
--deny-local Refuse local targets (localhost, 127.0.0.1, [::1], *.localhost, *.test) (exit 3); a redirect or request to one is blocked by the network guard and listed in the limitations;
|
|
170
|
+
JOURILO_DENY_LOCAL=1 does the same. Not available with --browser webkit (exit 3). For hosted integrations; a directory target is still served
|
|
171
|
+
--proxy URL Chain to an upstream HTTP proxy (http://[user:password@]host:port) behind the network guard;
|
|
172
|
+
default HTTPS_PROXY / HTTP_PROXY (either case; prefer the variable for credentials, argv shows
|
|
173
|
+
in ps). NO_PROXY is decided per destination host (NO_PROXY=* = no proxy). The guard resolves and
|
|
174
|
+
checks every destination itself, then tunnels to the checked address (CONNECT ip:443, and ip:80
|
|
175
|
+
for plain HTTP; a proxy that refuses port 80 fails those requests: give an https:// target);
|
|
176
|
+
loopback connects directly. The run records the proxy without its credentials
|
|
177
|
+
--allow-hosts LIST Only these hosts may be reached (comma-separated or repeated; *.example.com = its subdomains);
|
|
178
|
+
the target's own host is always allowed. Other hosts are refused and listed in the limitations
|
|
179
|
+
--block-hosts LIST Refuse these hosts (e.g. *.tracker.example); refused requests are listed in the limitations
|
|
180
|
+
--user-agent UA Send this User-Agent (also navigator.userAgent) instead of the browser's own; recorded in the run
|
|
181
|
+
--extra-header H Add a request header "Name: value" (repeatable), sent only to the target's origin, never
|
|
182
|
+
to other hosts: Jourilo makes those requests itself, so the headers cannot follow a redirect
|
|
183
|
+
elsewhere (a redirect is followed without them). The run records the names, never the values
|
|
184
|
+
--ignore-https-errors
|
|
185
|
+
Accept invalid or self-signed certificates in the browser (test environments only); the network
|
|
186
|
+
guard still checks every destination, and the run lists it in the limitations
|
|
187
|
+
--chromium-sandbox
|
|
188
|
+
Keep Chromium's own process sandbox (Playwright disables it by default); JOURILO_CHROMIUM_SANDBOX=1
|
|
189
|
+
does the same. Chromium, Chrome and Edge only (a usage error with Firefox or WebKit). Fails to launch
|
|
190
|
+
where the system denies the sandbox (containers, some Linux CI kernels)
|
|
110
191
|
--no-forms Skip the form validation probe
|
|
111
192
|
(by default, on local hosts, an empty submission is simulated: nothing that sends data
|
|
112
193
|
leaves the browser, so no database is written; server-side feedback is reported as untested)
|
|
@@ -115,10 +196,15 @@ Options:
|
|
|
115
196
|
also lets a --setup-journey submit forms
|
|
116
197
|
--sarif Also write report.sarif for code scanning
|
|
117
198
|
--fail-on SEVERITY Exit 1 if a defect at or above this severity exists (CI gate)
|
|
199
|
+
--budget LIST Exit 1 when a lab metric exceeds its limit, e.g. LCP=2000,CLS=0.05,TBT=300 (LCP, CLS, INP, FCP,
|
|
200
|
+
TTFB, TBT; ms, CLS unitless). Each capture's median is compared and the worst capture decides;
|
|
201
|
+
a metric no page measured (INP) is reported as not measured, not as a pass. Combines with --fail-on
|
|
118
202
|
--evidence MODE full (default) or minimal: keep first screens and only the full-page screenshots findings need; JPEG quality 55
|
|
119
|
-
--run-id ID Use this run id instead of a generated one (1-64 of A-Z a-z 0-9 _ -); refused
|
|
120
|
-
|
|
121
|
-
|
|
203
|
+
--run-id ID Use this run id instead of a generated one (1-64 of A-Z a-z 0-9 _ -); refused (exit 2) if its
|
|
204
|
+
directory exists, even without a run.json (left by a crashed run)
|
|
205
|
+
--max-duration SECS Stop after this many seconds (1 to 86400) and write a partial run (exit 6), as SIGINT/SIGTERM do;
|
|
206
|
+
the page in progress gets up to 3 s to finish, then it is left out; a second signal quits at
|
|
207
|
+
once (exit 130) after one line on stderr (STOPPED_TWICE with --json)
|
|
122
208
|
```
|
|
123
209
|
|
|
124
210
|
### `jourilo conversion`
|
|
@@ -131,7 +217,7 @@ jourilo conversion <url|dir> [audit options]
|
|
|
131
217
|
|
|
132
218
|
```
|
|
133
219
|
Options:
|
|
134
|
-
--pages N Pages to audit after discovery (default 6; 1 = only the target)
|
|
220
|
+
--pages N Pages to audit after discovery (default 6; 1 = only the target; 0 is a usage error)
|
|
135
221
|
--depth N Link depth for discovery (default 3)
|
|
136
222
|
--url PATH Audit exactly these paths/URLs on the target origin (repeatable; skips discovery)
|
|
137
223
|
--include PATH Add pages to discovery (repeatable)
|
|
@@ -140,6 +226,8 @@ Options:
|
|
|
140
226
|
--headed Show the browser window instead of running headless
|
|
141
227
|
--locale TAG Browser locale for every page (e.g. tr-TR); sets Accept-Language and navigator.language
|
|
142
228
|
--timeout SECS Per-page navigation timeout in seconds (default 30)
|
|
229
|
+
--wait-for SELECTOR Capture each page only once this element is visible (client-rendered pages); if it never appears within
|
|
230
|
+
--timeout the page is still audited, with a limitation. Each capture records how it loaded
|
|
143
231
|
--throttle Simulate a mid-range phone network and 4x CPU slowdown (Chromium)
|
|
144
232
|
--runs N Visits per page and viewport for lab metrics; reports the median and range (default 1, max 9)
|
|
145
233
|
--no-keyboard Skip the keyboard-only walk
|
|
@@ -153,6 +241,28 @@ Options:
|
|
|
153
241
|
--brand SLUG Markilo brand to check design consistency against (default: master brand)
|
|
154
242
|
--ignore-robots Ignore robots.txt (only for sites you own or are authorized to test)
|
|
155
243
|
--allow-private Allow private-network hosts (10.x, 192.168.x, ...)
|
|
244
|
+
--deny-local Refuse local targets (localhost, 127.0.0.1, [::1], *.localhost, *.test) (exit 3); a redirect or request to one is blocked by the network guard and listed in the limitations;
|
|
245
|
+
JOURILO_DENY_LOCAL=1 does the same. Not available with --browser webkit (exit 3). For hosted integrations; a directory target is still served
|
|
246
|
+
--proxy URL Chain to an upstream HTTP proxy (http://[user:password@]host:port) behind the network guard;
|
|
247
|
+
default HTTPS_PROXY / HTTP_PROXY (either case; prefer the variable for credentials, argv shows
|
|
248
|
+
in ps). NO_PROXY is decided per destination host (NO_PROXY=* = no proxy). The guard resolves and
|
|
249
|
+
checks every destination itself, then tunnels to the checked address (CONNECT ip:443, and ip:80
|
|
250
|
+
for plain HTTP; a proxy that refuses port 80 fails those requests: give an https:// target);
|
|
251
|
+
loopback connects directly. The run records the proxy without its credentials
|
|
252
|
+
--allow-hosts LIST Only these hosts may be reached (comma-separated or repeated; *.example.com = its subdomains);
|
|
253
|
+
the target's own host is always allowed. Other hosts are refused and listed in the limitations
|
|
254
|
+
--block-hosts LIST Refuse these hosts (e.g. *.tracker.example); refused requests are listed in the limitations
|
|
255
|
+
--user-agent UA Send this User-Agent (also navigator.userAgent) instead of the browser's own; recorded in the run
|
|
256
|
+
--extra-header H Add a request header "Name: value" (repeatable), sent only to the target's origin, never
|
|
257
|
+
to other hosts: Jourilo makes those requests itself, so the headers cannot follow a redirect
|
|
258
|
+
elsewhere (a redirect is followed without them). The run records the names, never the values
|
|
259
|
+
--ignore-https-errors
|
|
260
|
+
Accept invalid or self-signed certificates in the browser (test environments only); the network
|
|
261
|
+
guard still checks every destination, and the run lists it in the limitations
|
|
262
|
+
--chromium-sandbox
|
|
263
|
+
Keep Chromium's own process sandbox (Playwright disables it by default); JOURILO_CHROMIUM_SANDBOX=1
|
|
264
|
+
does the same. Chromium, Chrome and Edge only (a usage error with Firefox or WebKit). Fails to launch
|
|
265
|
+
where the system denies the sandbox (containers, some Linux CI kernels)
|
|
156
266
|
--no-forms Skip the form validation probe
|
|
157
267
|
(by default, on local hosts, an empty submission is simulated: nothing that sends data
|
|
158
268
|
leaves the browser, so no database is written; server-side feedback is reported as untested)
|
|
@@ -161,10 +271,15 @@ Options:
|
|
|
161
271
|
also lets a --setup-journey submit forms
|
|
162
272
|
--sarif Also write report.sarif for code scanning
|
|
163
273
|
--fail-on SEVERITY Exit 1 if a defect at or above this severity exists (CI gate)
|
|
274
|
+
--budget LIST Exit 1 when a lab metric exceeds its limit, e.g. LCP=2000,CLS=0.05,TBT=300 (LCP, CLS, INP, FCP,
|
|
275
|
+
TTFB, TBT; ms, CLS unitless). Each capture's median is compared and the worst capture decides;
|
|
276
|
+
a metric no page measured (INP) is reported as not measured, not as a pass. Combines with --fail-on
|
|
164
277
|
--evidence MODE full (default) or minimal: keep first screens and only the full-page screenshots findings need; JPEG quality 55
|
|
165
|
-
--run-id ID Use this run id instead of a generated one (1-64 of A-Z a-z 0-9 _ -); refused
|
|
166
|
-
|
|
167
|
-
|
|
278
|
+
--run-id ID Use this run id instead of a generated one (1-64 of A-Z a-z 0-9 _ -); refused (exit 2) if its
|
|
279
|
+
directory exists, even without a run.json (left by a crashed run)
|
|
280
|
+
--max-duration SECS Stop after this many seconds (1 to 86400) and write a partial run (exit 6), as SIGINT/SIGTERM do;
|
|
281
|
+
the page in progress gets up to 3 s to finish, then it is left out; a second signal quits at
|
|
282
|
+
once (exit 130) after one line on stderr (STOPPED_TWICE with --json)
|
|
168
283
|
```
|
|
169
284
|
|
|
170
285
|
## Journeys
|
|
@@ -188,6 +303,28 @@ Suggest options:
|
|
|
188
303
|
--pages N Pages to read when deriving journeys from a site (default 8)
|
|
189
304
|
--force Overwrite journey files that already exist (by default existing files are kept)
|
|
190
305
|
--allow-private Allow private-network hosts (10.x, 192.168.x, ...)
|
|
306
|
+
--deny-local Refuse local targets (localhost, 127.0.0.1, [::1], *.localhost, *.test) (exit 3); a redirect or request to one is blocked by the network guard and listed in the limitations;
|
|
307
|
+
JOURILO_DENY_LOCAL=1 does the same
|
|
308
|
+
--proxy URL Chain to an upstream HTTP proxy (http://[user:password@]host:port) behind the network guard;
|
|
309
|
+
default HTTPS_PROXY / HTTP_PROXY (either case; prefer the variable for credentials, argv shows
|
|
310
|
+
in ps). NO_PROXY is decided per destination host (NO_PROXY=* = no proxy). The guard resolves and
|
|
311
|
+
checks every destination itself, then tunnels to the checked address (CONNECT ip:443, and ip:80
|
|
312
|
+
for plain HTTP; a proxy that refuses port 80 fails those requests: give an https:// target);
|
|
313
|
+
loopback connects directly. The run records the proxy without its credentials
|
|
314
|
+
--allow-hosts LIST Only these hosts may be reached (comma-separated or repeated; *.example.com = its subdomains);
|
|
315
|
+
the target's own host is always allowed. Other hosts are refused and listed in the limitations
|
|
316
|
+
--block-hosts LIST Refuse these hosts (e.g. *.tracker.example); refused requests are listed in the limitations
|
|
317
|
+
--user-agent UA Send this User-Agent (also navigator.userAgent) instead of the browser's own; recorded in the run
|
|
318
|
+
--extra-header H Add a request header "Name: value" (repeatable), sent only to the target's origin, never
|
|
319
|
+
to other hosts: Jourilo makes those requests itself, so the headers cannot follow a redirect
|
|
320
|
+
elsewhere (a redirect is followed without them). The run records the names, never the values
|
|
321
|
+
--ignore-https-errors
|
|
322
|
+
Accept invalid or self-signed certificates in the browser (test environments only); the network
|
|
323
|
+
guard still checks every destination, and the run lists it in the limitations
|
|
324
|
+
--chromium-sandbox
|
|
325
|
+
Keep Chromium's own process sandbox (Playwright disables it by default); JOURILO_CHROMIUM_SANDBOX=1
|
|
326
|
+
does the same. Chromium, Chrome and Edge only (a usage error with Firefox or WebKit). Fails to launch
|
|
327
|
+
where the system denies the sandbox (containers, some Linux CI kernels)
|
|
191
328
|
|
|
192
329
|
Run options:
|
|
193
330
|
--base URL|DIR The site or static build to run against (required)
|
|
@@ -200,7 +337,8 @@ Run options:
|
|
|
200
337
|
--allow-submit Allow form submission on non-local hosts (authorized test environments only)
|
|
201
338
|
--allow-destructive Allow irreversible/payment actions — local hosts with sandbox data only
|
|
202
339
|
--allow-origin ORIGIN Let the page navigate to another origin you are authorized to test (e.g. a test IdP)
|
|
203
|
-
--trace Record a Playwright trace per journey (contains typed values; keep private)
|
|
340
|
+
--trace Record a Playwright trace per journey (contains typed values; keep private);
|
|
341
|
+
refused with --extra-header, since a trace records header values
|
|
204
342
|
--auth FILE Playwright storage state for signed-in journeys
|
|
205
343
|
--save-auth FILE After a passing sign-in journey (exactly one), save its session for --auth (test accounts only)
|
|
206
344
|
--timezone ZONE IANA time zone for the page (e.g. Europe/Istanbul)
|
|
@@ -208,6 +346,28 @@ Run options:
|
|
|
208
346
|
--evidence MODE full (default) or minimal: keep only the screenshots of the failed step, the step before it and the last step
|
|
209
347
|
--repeat N Run each journey N times (max 10); mixed outcomes are reported as flaky
|
|
210
348
|
--allow-private Allow private-network hosts (10.x, 192.168.x, ...)
|
|
349
|
+
--deny-local Refuse local targets (localhost, 127.0.0.1, [::1], *.localhost, *.test) (exit 3); a redirect or request to one is blocked by the network guard and listed in the limitations;
|
|
350
|
+
JOURILO_DENY_LOCAL=1 does the same. Not available with --browser webkit (exit 3)
|
|
351
|
+
--proxy URL Chain to an upstream HTTP proxy (http://[user:password@]host:port) behind the network guard;
|
|
352
|
+
default HTTPS_PROXY / HTTP_PROXY (either case; prefer the variable for credentials, argv shows
|
|
353
|
+
in ps). NO_PROXY is decided per destination host (NO_PROXY=* = no proxy). The guard resolves and
|
|
354
|
+
checks every destination itself, then tunnels to the checked address (CONNECT ip:443, and ip:80
|
|
355
|
+
for plain HTTP; a proxy that refuses port 80 fails those requests: give an https:// target);
|
|
356
|
+
loopback connects directly. The run records the proxy without its credentials
|
|
357
|
+
--allow-hosts LIST Only these hosts may be reached (comma-separated or repeated; *.example.com = its subdomains);
|
|
358
|
+
the target's own host is always allowed. Other hosts are refused and listed in the limitations
|
|
359
|
+
--block-hosts LIST Refuse these hosts (e.g. *.tracker.example); refused requests are listed in the limitations
|
|
360
|
+
--user-agent UA Send this User-Agent (also navigator.userAgent) instead of the browser's own; recorded in the run
|
|
361
|
+
--extra-header H Add a request header "Name: value" (repeatable), sent only to the target's origin, never
|
|
362
|
+
to other hosts: Jourilo makes those requests itself, so the headers cannot follow a redirect
|
|
363
|
+
elsewhere (a redirect is followed without them). The run records the names, never the values
|
|
364
|
+
--ignore-https-errors
|
|
365
|
+
Accept invalid or self-signed certificates in the browser (test environments only); the network
|
|
366
|
+
guard still checks every destination, and the run lists it in the limitations
|
|
367
|
+
--chromium-sandbox
|
|
368
|
+
Keep Chromium's own process sandbox (Playwright disables it by default); JOURILO_CHROMIUM_SANDBOX=1
|
|
369
|
+
does the same. Chromium, Chrome and Edge only (a usage error with Firefox or WebKit). Fails to launch
|
|
370
|
+
where the system denies the sandbox (containers, some Linux CI kernels)
|
|
211
371
|
--fail-on-failure Exit 1 when a journey fails
|
|
212
372
|
|
|
213
373
|
Safety: payment, purchase, delete and cancel actions are never performed on non-local hosts; form submission
|
|
@@ -273,6 +433,31 @@ jourilo verify <baseline-run> [--target url|dir] [--fail-on-regression]
|
|
|
273
433
|
Options:
|
|
274
434
|
--target URL|DIR Where to repeat the audit (default: the baseline run's target)
|
|
275
435
|
--repo PATH Repository for source mapping (default: the baseline run's repo)
|
|
436
|
+
--deny-local Refuse a local target (localhost, 127.0.0.1, [::1], *.localhost, *.test) with exit 3; a redirect to one is blocked by the network guard and listed in the limitations;
|
|
437
|
+
JOURILO_DENY_LOCAL=1 does the same. Not available with --browser webkit (exit 3)
|
|
438
|
+
--proxy URL Chain to an upstream HTTP proxy (http://[user:password@]host:port) behind the network guard;
|
|
439
|
+
default HTTPS_PROXY / HTTP_PROXY (either case; prefer the variable for credentials, argv shows
|
|
440
|
+
in ps). NO_PROXY is decided per destination host (NO_PROXY=* = no proxy). The guard resolves and
|
|
441
|
+
checks every destination itself, then tunnels to the checked address (CONNECT ip:443, and ip:80
|
|
442
|
+
for plain HTTP; a proxy that refuses port 80 fails those requests: give an https:// target);
|
|
443
|
+
loopback connects directly. The run records the proxy without its credentials
|
|
444
|
+
--allow-hosts LIST Only these hosts may be reached (comma-separated or repeated; *.example.com = its subdomains);
|
|
445
|
+
the target's own host is always allowed. Other hosts are refused and listed in the limitations
|
|
446
|
+
--block-hosts LIST Refuse these hosts (e.g. *.tracker.example); refused requests are listed in the limitations
|
|
447
|
+
--user-agent UA Send this User-Agent (also navigator.userAgent) instead of the browser's own; recorded in the run
|
|
448
|
+
--extra-header H Add a request header "Name: value" (repeatable), sent only to the target's origin, never
|
|
449
|
+
to other hosts: Jourilo makes those requests itself, so the headers cannot follow a redirect
|
|
450
|
+
elsewhere (a redirect is followed without them). The run records the names, never the values
|
|
451
|
+
--ignore-https-errors
|
|
452
|
+
Accept invalid or self-signed certificates in the browser (test environments only); the network
|
|
453
|
+
guard still checks every destination, and the run lists it in the limitations
|
|
454
|
+
--chromium-sandbox
|
|
455
|
+
Keep Chromium's own process sandbox (Playwright disables it by default); JOURILO_CHROMIUM_SANDBOX=1
|
|
456
|
+
does the same. Chromium, Chrome and Edge only (a usage error with Firefox or WebKit). Fails to launch
|
|
457
|
+
where the system denies the sandbox (containers, some Linux CI kernels)
|
|
458
|
+
Without --allow-hosts / --block-hosts, the baseline run's lists are used again; so are its
|
|
459
|
+
--user-agent and --ignore-https-errors. Header values are never stored: a baseline that sent
|
|
460
|
+
--extra-header needs the headers again (exit 2 without them)
|
|
276
461
|
--fail-on-regression Exit 1 when new serious or critical defects appear
|
|
277
462
|
```
|
|
278
463
|
|
|
@@ -394,6 +579,23 @@ Benchmark detection quality on fixture sites with known defects (recall, false p
|
|
|
394
579
|
jourilo bench [fixtures-dir=fixtures/sites] [--only name] [--record docs/evaluation/bench-history.jsonl]
|
|
395
580
|
```
|
|
396
581
|
|
|
582
|
+
### `jourilo rules`
|
|
583
|
+
|
|
584
|
+
List every rule Jourilo can report, with category, severity and kind (machine-readable with --json).
|
|
585
|
+
|
|
586
|
+
```
|
|
587
|
+
jourilo rules list [--json]
|
|
588
|
+
```
|
|
589
|
+
|
|
590
|
+
```
|
|
591
|
+
Subcommand:
|
|
592
|
+
list Native rules (jourilo/…, perf/…, conv/…, ux/…, a11y/…, journey/…, design/…) and the axe/<id> and
|
|
593
|
+
axe-review/<id> rules a run enables from axe-core 4.14.0. Severity is "varies" when it depends on
|
|
594
|
+
what was measured; kind is "varies" for a rule that reports a defect or, when unsure, a needs-review
|
|
595
|
+
item. With --json: {"jourilo": <version>, "axe": <axe-core version>, "rules": [{id, category,
|
|
596
|
+
severity, kind, title, standards}, …]}.
|
|
597
|
+
```
|
|
598
|
+
|
|
397
599
|
### `jourilo serve`
|
|
398
600
|
|
|
399
601
|
Serve a static build directory on 127.0.0.1 (for audits and journeys of static sites).
|
package/schemas/run.schema.json
CHANGED
|
@@ -59,6 +59,41 @@
|
|
|
59
59
|
},
|
|
60
60
|
"axe": { "type": ["string", "null"] },
|
|
61
61
|
"hostClass": { "type": "string" },
|
|
62
|
+
"proxy": {
|
|
63
|
+
"type": "string",
|
|
64
|
+
"description": "Upstream proxy the run chained to behind the network guard (scheme://host:port, never credentials)."
|
|
65
|
+
},
|
|
66
|
+
"allowHosts": {
|
|
67
|
+
"type": "array",
|
|
68
|
+
"items": { "type": "string" },
|
|
69
|
+
"description": "--allow-hosts patterns as given; the target's own host was always allowed."
|
|
70
|
+
},
|
|
71
|
+
"blockHosts": {
|
|
72
|
+
"type": "array",
|
|
73
|
+
"items": { "type": "string" },
|
|
74
|
+
"description": "--block-hosts patterns."
|
|
75
|
+
},
|
|
76
|
+
"userAgent": {
|
|
77
|
+
"type": "string",
|
|
78
|
+
"description": "--user-agent the browser sent instead of its own."
|
|
79
|
+
},
|
|
80
|
+
"extraHeaders": {
|
|
81
|
+
"type": "array",
|
|
82
|
+
"items": { "type": "string" },
|
|
83
|
+
"description": "Names of the --extra-header headers, sent only to the target's origin; their values are never stored."
|
|
84
|
+
},
|
|
85
|
+
"ignoreHttpsErrors": {
|
|
86
|
+
"type": "boolean",
|
|
87
|
+
"description": "--ignore-https-errors: the browser accepted invalid certificates; the network guard still checked every destination."
|
|
88
|
+
},
|
|
89
|
+
"waitFor": {
|
|
90
|
+
"type": "string",
|
|
91
|
+
"description": "--wait-for: each page was captured once this selector was visible (or --timeout passed; see limitations)."
|
|
92
|
+
},
|
|
93
|
+
"chromiumSandbox": {
|
|
94
|
+
"type": "boolean",
|
|
95
|
+
"description": "--chromium-sandbox: Chromium ran with its process sandbox on (Playwright disables it by default)."
|
|
96
|
+
},
|
|
62
97
|
"scope": {
|
|
63
98
|
"type": "object",
|
|
64
99
|
"properties": {
|
|
@@ -123,6 +158,36 @@
|
|
|
123
158
|
"description": "Why a partial run stopped.",
|
|
124
159
|
"enum": ["signal", "max-duration"]
|
|
125
160
|
},
|
|
161
|
+
"budgets": {
|
|
162
|
+
"description": "`--budget` results: per metric, the worst capture's value (the median with --runs N). `ok` is null when no capture measured the metric.",
|
|
163
|
+
"type": "array",
|
|
164
|
+
"items": {
|
|
165
|
+
"type": "object",
|
|
166
|
+
"required": ["metric", "limit", "worst", "url", "viewport", "ok"],
|
|
167
|
+
"properties": {
|
|
168
|
+
"metric": { "type": "string" },
|
|
169
|
+
"limit": { "type": "number" },
|
|
170
|
+
"worst": { "type": ["number", "null"] },
|
|
171
|
+
"url": { "type": ["string", "null"] },
|
|
172
|
+
"viewport": { "type": ["string", "null"] },
|
|
173
|
+
"ok": { "type": ["boolean", "null"] }
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
},
|
|
177
|
+
"sample": {
|
|
178
|
+
"description": "Present when discovery found more pages than were audited.",
|
|
179
|
+
"type": "object",
|
|
180
|
+
"required": ["discovered", "audited", "leftOut"],
|
|
181
|
+
"properties": {
|
|
182
|
+
"discovered": { "type": "integer" },
|
|
183
|
+
"audited": { "type": "integer" },
|
|
184
|
+
"leftOut": {
|
|
185
|
+
"description": "At most 20 URLs (redacted) that were discovered but not audited.",
|
|
186
|
+
"type": "array",
|
|
187
|
+
"items": { "type": "string" }
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
},
|
|
126
191
|
"dismissed": {
|
|
127
192
|
"description": "Findings a person or agent dismissed. Not counted in summary.",
|
|
128
193
|
"type": "array",
|
|
@@ -180,7 +245,9 @@
|
|
|
180
245
|
"type": "object",
|
|
181
246
|
"required": ["pages", "journeys", "findings", "byCategory", "byKind"],
|
|
182
247
|
"properties": {
|
|
183
|
-
"pages": { "type": "integer" },
|
|
248
|
+
"pages": { "type": "integer", "description": "Page captures (URL x viewport), not distinct URLs." },
|
|
249
|
+
"urls": { "type": "integer", "description": "Distinct page URLs that were audited." },
|
|
250
|
+
"captures": { "type": "integer", "description": "Page captures; equal to `pages`." },
|
|
184
251
|
"journeys": { "type": "integer" },
|
|
185
252
|
"findings": { "type": "object", "additionalProperties": { "type": "integer" } },
|
|
186
253
|
"byCategory": { "type": "object", "additionalProperties": { "type": "integer" } },
|
|
@@ -324,10 +391,24 @@
|
|
|
324
391
|
"title": { "type": "string" },
|
|
325
392
|
"viewport": { "type": "string" },
|
|
326
393
|
"screenshot": { "type": "string", "description": "Path relative to the run directory." },
|
|
394
|
+
"foldScreenshot": {
|
|
395
|
+
"type": "string",
|
|
396
|
+
"description": "First-screen screenshot, relative to the run directory."
|
|
397
|
+
},
|
|
327
398
|
"loadMs": { "type": "number" },
|
|
328
399
|
"metrics": { "type": "array", "items": { "$ref": "#/$defs/metric" } },
|
|
329
400
|
"consoleErrors": { "type": "integer" },
|
|
330
401
|
"failedRequests": { "type": "integer" },
|
|
402
|
+
"load": {
|
|
403
|
+
"type": "object",
|
|
404
|
+
"description": "How the page was captured. `waitedFor` and `found` are present with --wait-for; `found` false means the element never became visible within --timeout.",
|
|
405
|
+
"required": ["networkIdle"],
|
|
406
|
+
"properties": {
|
|
407
|
+
"networkIdle": { "type": "boolean" },
|
|
408
|
+
"waitedFor": { "type": "string" },
|
|
409
|
+
"found": { "type": "boolean" }
|
|
410
|
+
}
|
|
411
|
+
},
|
|
331
412
|
"inventory": { "$ref": "#/$defs/inventory" }
|
|
332
413
|
}
|
|
333
414
|
},
|
|
@@ -527,12 +608,40 @@
|
|
|
527
608
|
}
|
|
528
609
|
},
|
|
529
610
|
"manifest": {
|
|
530
|
-
"description": "manifest.json, written next to run.json: every artifact of the run with its size and sha256.",
|
|
611
|
+
"description": "manifest.json, written next to run.json: every artifact of the run with its size and sha256, and the versions and scope that produced them.",
|
|
531
612
|
"type": "object",
|
|
532
613
|
"required": ["schemaVersion", "runId", "files"],
|
|
533
614
|
"properties": {
|
|
534
615
|
"schemaVersion": { "const": 1 },
|
|
535
616
|
"runId": { "type": "string" },
|
|
617
|
+
"tool": {
|
|
618
|
+
"description": "The Jourilo release that made the run (run.tool). Absent in manifests written before 1.3.0.",
|
|
619
|
+
"type": "object",
|
|
620
|
+
"required": ["name", "version"],
|
|
621
|
+
"properties": { "name": { "const": "jourilo" }, "version": { "type": "string" } }
|
|
622
|
+
},
|
|
623
|
+
"browser": {
|
|
624
|
+
"description": "The browser and its version (run.browser).",
|
|
625
|
+
"type": "object",
|
|
626
|
+
"required": ["name", "version"],
|
|
627
|
+
"properties": { "name": { "type": "string" }, "version": { "type": "string" } }
|
|
628
|
+
},
|
|
629
|
+
"axe": {
|
|
630
|
+
"description": "The axe-core version the pages were checked with (settings.axe), or the bundled one when no page was checked.",
|
|
631
|
+
"type": "object",
|
|
632
|
+
"required": ["version"],
|
|
633
|
+
"properties": { "version": { "type": "string" } }
|
|
634
|
+
},
|
|
635
|
+
"scope": {
|
|
636
|
+
"description": "What the run covered: the redacted target, the audited URLs (redacted; settings.scope.urls, else the captured pages) and the viewport names.",
|
|
637
|
+
"type": "object",
|
|
638
|
+
"required": ["target", "urls", "viewports"],
|
|
639
|
+
"properties": {
|
|
640
|
+
"target": { "type": "string" },
|
|
641
|
+
"urls": { "type": "array", "items": { "type": "string" } },
|
|
642
|
+
"viewports": { "type": "array", "items": { "type": "string" } }
|
|
643
|
+
}
|
|
644
|
+
},
|
|
536
645
|
"files": {
|
|
537
646
|
"type": "array",
|
|
538
647
|
"items": {
|