kaloko 0.4.11 → 0.5.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 +45 -4
- package/package.json +1 -1
- package/schemas/config.v1.json +42 -2
- package/schemas/run.v1.json +33 -2
- package/schemas/scenario.v1.json +107 -16
- package/skills/kaloko/SKILL.md +8 -2
- package/skills/kaloko/reference/acceptance.md +70 -1
- package/skills/kaloko/reference/apps.md +103 -8
- package/skills/kaloko/reference/ci.md +3 -1
- package/skills/kaloko/reference/design.md +39 -0
- package/skills/kaloko/reference/devices.md +109 -0
- package/skills/kaloko/reference/environments.md +6 -0
- package/skills/kaloko/reference/execution.md +6 -0
- package/src/cli.mjs +326 -190
- package/src/lib/access.mjs +5 -2
- package/src/lib/apps/devices.mjs +187 -0
- package/src/lib/apps/drivers.mjs +11 -3
- package/src/lib/apps/ios-device.mjs +78 -0
- package/src/lib/apps/tree.mjs +9 -1
- package/src/lib/apps/webview.mjs +54 -0
- package/src/lib/apps/windows.mjs +108 -0
- package/src/lib/apps/windows.ps1 +78 -0
- package/src/lib/assertions.mjs +300 -0
- package/src/lib/build.mjs +4 -1
- package/src/lib/capture.mjs +146 -119
- package/src/lib/ci.mjs +8 -4
- package/src/lib/design-cli.mjs +35 -6
- package/src/lib/design.mjs +3 -1
- package/src/lib/devices.mjs +85 -0
- package/src/lib/devspec.mjs +3 -2
- package/src/lib/dimensions.mjs +326 -0
- package/src/lib/doctor.mjs +31 -6
- package/src/lib/drift.mjs +8 -4
- package/src/lib/evaluate.mjs +25 -7
- package/src/lib/import.mjs +2 -1
- package/src/lib/jev.mjs +3 -1
- package/src/lib/manifest-core.mjs +12 -3
- package/src/lib/probe.mjs +60 -0
- package/src/lib/recheck.mjs +6 -1
- package/src/lib/scenario.mjs +3 -0
- package/src/lib/stability-core.mjs +4 -2
- package/src/lib/walk-dimensions.mjs +83 -0
- package/viewer/index.html +282 -19
|
@@ -6,13 +6,19 @@ driver differs, and it is chosen by the scenario's `platform`.
|
|
|
6
6
|
|
|
7
7
|
| platform | Driven by | UI tree | Interactions |
|
|
8
8
|
|---|---|---|---|
|
|
9
|
-
| `android` | `adb
|
|
9
|
+
| `android` | `adb`: emulator, USB phone or a phone over Wi-Fi | uiautomator, in dp | deep links, tap by selector or point, type, back |
|
|
10
10
|
| `ios` | `xcrun simctl` (iOS Simulator) | `idb` when installed, otherwise text by OCR (macOS Vision) | deep links; taps and typing need `idb` |
|
|
11
|
+
| `ios` + `real: true` | `xcrun devicectl` and `idevicescreenshot` or `pymobiledevice3` (a real iPhone) | text by OCR | install, launch, deep links; no taps |
|
|
11
12
|
| `electron` | Playwright Electron | the full DOM: every web check applies | everything Playwright does (`page`) |
|
|
12
13
|
| `desktop` | macOS window of a named app | macOS accessibility tree, otherwise OCR | none built in: use your tool, AppleScript or a person |
|
|
14
|
+
| `windows` | the app's window through Windows PowerShell and UI Automation (nothing to install) | UI Automation tree | tap by selector or point, type; walk on Windows |
|
|
13
15
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
+
An installed web app (PWA) is a web scenario with `display_modes: [standalone]`; see
|
|
17
|
+
[devices.md](devices.md). A WebView inside an Android app is captured as a web page; see
|
|
18
|
+
[WebViews](#webviews-inside-apps).
|
|
19
|
+
|
|
20
|
+
Anything else, including Flutter or React Native under Detox, Maestro flows,
|
|
21
|
+
XCUITest or Appium runs, is captured by import:
|
|
16
22
|
|
|
17
23
|
```bash
|
|
18
24
|
npx kaloko capture --step checkout --image shot.png --tree hierarchy.xml --device "Pixel 8" --density 2.625
|
|
@@ -24,6 +30,7 @@ npx kaloko capture --step checkout --image shot.png --tree hierarchy.xml --devic
|
|
|
24
30
|
- Appium iOS XML (`XCUIElementType…`);
|
|
25
31
|
- `idb ui describe-all --json`;
|
|
26
32
|
- Maestro `hierarchy` JSON;
|
|
33
|
+
- Windows UI Automation JSON from Kaloko's `windows.ps1 tree` (`--platform windows`);
|
|
27
34
|
- Kaloko's own `qawalk.tree.v1`.
|
|
28
35
|
|
|
29
36
|
`--ocr` reads the text from the image instead (macOS). `--density` or
|
|
@@ -46,6 +53,7 @@ environments:
|
|
|
46
53
|
app:
|
|
47
54
|
electron: { main: dist/main.js } # or executable: path to the packaged app
|
|
48
55
|
# desktop: { name: Notes } # a macOS app by its window owner name
|
|
56
|
+
# windows: { name: contoso, path: dist/Contoso.exe } # or aumid: a Store/MSIX app
|
|
49
57
|
```
|
|
50
58
|
|
|
51
59
|
```yaml
|
|
@@ -81,9 +89,50 @@ nodes:
|
|
|
81
89
|
- The app language is set per locale: Android 13+ app locales, iOS
|
|
82
90
|
`-AppleLanguages`, Electron `--lang`.
|
|
83
91
|
|
|
92
|
+
## Devices, dark mode and motion
|
|
93
|
+
|
|
94
|
+
`devices:` walks the same scenario on several emulators, simulators or phones; each device is its own capture key
|
|
95
|
+
next to the colour schemes and motion of the run:
|
|
96
|
+
|
|
97
|
+
```yaml
|
|
98
|
+
# qa/flows/shop-android.yml
|
|
99
|
+
platform: android
|
|
100
|
+
devices: [pixel-8-api-34, pixel-7-api-33, galaxy]
|
|
101
|
+
color_schemes: [light, dark]
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
```yaml
|
|
105
|
+
# kaloko.config.yml
|
|
106
|
+
environments:
|
|
107
|
+
staging:
|
|
108
|
+
app:
|
|
109
|
+
android:
|
|
110
|
+
package: com.acme.shop.staging
|
|
111
|
+
devices:
|
|
112
|
+
galaxy: { connect: 192.168.1.20:5555, title: Galaxy S24 } # a phone over Wi-Fi
|
|
113
|
+
ios:
|
|
114
|
+
bundle: com.acme.shop
|
|
115
|
+
devices:
|
|
116
|
+
my-iphone: { udid: 00008110-000A…, real: true, title: Test iPhone }
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
- A name without an entry says what it is. Android: an adb serial (`emulator-5554`, `R58M…`, `host:port`) or an
|
|
120
|
+
AVD name (`pixel-8-api-34` finds `Pixel_8_API_34`; Kaloko starts it headless when it is not running). iOS: a
|
|
121
|
+
simulator by name and runtime (`iphone-15-ios-18` is "iPhone 15" on iOS 18; `iphone-se-3` is "iPhone SE (3rd
|
|
122
|
+
generation)").
|
|
123
|
+
- `kaloko start --devices pixel-8-api-34` overrides the scenario; `kaloko walk --devices galaxy` walks one of them.
|
|
124
|
+
- Real Android phones are woken up and unlocked (no PIN) and get a clean status bar (demo mode, 9:41, full battery).
|
|
125
|
+
`wake: false` and `status_bar: false` turn that off.
|
|
126
|
+
- Dark mode and reduced motion are set on the device per capture: `cmd uimode night` and the animator scales on
|
|
127
|
+
Android (the app redraws; some apps recreate the screen), `simctl ui appearance` on the iOS Simulator, emulated
|
|
128
|
+
media in Electron. The iOS Simulator has no command for reduced motion, and real devices keep their own setting;
|
|
129
|
+
the capture notes it.
|
|
130
|
+
- The canvas draws the device frame of the closest preset (`pixel-8-api-34` → Pixel 8) and offers the safe-area
|
|
131
|
+
overlay; app captures are the whole screen.
|
|
132
|
+
|
|
84
133
|
**Step scripts**
|
|
85
134
|
|
|
86
|
-
A script gets `{ app, page, locale, env, run, capture, link }`:
|
|
135
|
+
A script gets `{ app, page, webview, device, locale, env, run, capture, link }`:
|
|
87
136
|
|
|
88
137
|
```js
|
|
89
138
|
// steps/add-to-cart.mjs
|
|
@@ -97,9 +146,52 @@ export default async ({ app, link, capture }) => {
|
|
|
97
146
|
```
|
|
98
147
|
|
|
99
148
|
- `app.tap`, `app.wait` and `app.type` take app selectors. `app.tap({ x, y })`
|
|
100
|
-
taps by coordinates, in dp or points.
|
|
149
|
+
taps by coordinates, in dp or points (logical pixels on Windows).
|
|
101
150
|
- On Electron, selectors are CSS and `page` is the Playwright page, so
|
|
102
151
|
any Playwright code works there.
|
|
152
|
+
- `capture()` takes every key of the current device (light and dark);
|
|
153
|
+
`capture({ viewport: 'pixel-8-api-34.dark' })` one of them.
|
|
154
|
+
|
|
155
|
+
## WebViews inside apps
|
|
156
|
+
|
|
157
|
+
An Android WebView with debugging on (`WebView.setWebContentsDebuggingEnabled(true)` in debug builds) is a Chromium
|
|
158
|
+
page. `await webview()` in a step script returns it as a Playwright page (Kaloko forwards its DevTools socket with
|
|
159
|
+
adb), and `capture({ webview: true })`, or `webview: true` in `app.android`, captures it as a web page: the DOM, the
|
|
160
|
+
web checks, the accessibility basics. The native screen around it is not in that capture; capture both when both
|
|
161
|
+
matter.
|
|
162
|
+
|
|
163
|
+
iOS WKWebViews (`isInspectable`) speak Safari's Web Inspector protocol, which Playwright cannot attach to. Capture
|
|
164
|
+
those screens as app screens (tree or OCR), and test the web content itself as a web scenario in WebKit
|
|
165
|
+
(`browsers: [webkit]`) with an iPhone preset.
|
|
166
|
+
|
|
167
|
+
## Windows apps
|
|
168
|
+
|
|
169
|
+
`platform: windows` with `app.windows: { name, path | aumid, args }` walks a desktop app on Windows through the
|
|
170
|
+
PowerShell every Windows has: the window as a screenshot (at its display scale), the UI Automation tree (control
|
|
171
|
+
types, AutomationId, names, values), clicks by selector and typing (SendKeys). It needs a signed-in desktop session
|
|
172
|
+
(a person's machine, or a `windows-latest` CI runner); a locked screen or a service account cannot see windows.
|
|
173
|
+
Elsewhere, take the screenshots on Windows and import them with
|
|
174
|
+
`kaloko capture --image shot.png --tree uia.json --platform windows`, or run `kaloko import` on a folder of
|
|
175
|
+
screenshots.
|
|
176
|
+
|
|
177
|
+
## Real iPhones
|
|
178
|
+
|
|
179
|
+
`real: true` with the `udid` uses Xcode's `devicectl` to install (`app:` a `.app` or `.ipa` signed for the device),
|
|
180
|
+
launch and open deep links, and `idevicescreenshot` (`brew install libimobiledevice`) or `pymobiledevice3` for the
|
|
181
|
+
screenshot. On iOS 17 and newer, `pymobiledevice3` needs its tunnel running (`sudo pymobiledevice3 remote tunneld`).
|
|
182
|
+
There is no UI tree or tapping on a real device: text comes from OCR on macOS, and flows that need taps run in
|
|
183
|
+
XCUITest, Maestro or Appium, with each screen imported by `kaloko capture --image`.
|
|
184
|
+
|
|
185
|
+
## React Native and Flutter
|
|
186
|
+
|
|
187
|
+
- **React Native** renders native views: `testID` becomes the Android resource-id and the iOS accessibility id, so
|
|
188
|
+
`[id$=checkout]` selectors work; `accessibilityLabel` becomes the name `app_labels` checks. Deep links through
|
|
189
|
+
React Navigation linking work as step paths.
|
|
190
|
+
- **Flutter** draws its own widgets. The UI tree only has what the semantics tree exposes: wrap controls in
|
|
191
|
+
`Semantics(label: …)` or give them `Key`s that reach the accessibility layer, otherwise checks see one big view.
|
|
192
|
+
Flutter web builds are a web scenario. For taps, Maestro handles Flutter well; import its screens.
|
|
193
|
+
- Both: keep a debug or staging flavour with a stable package name per environment, and deep links into every screen
|
|
194
|
+
a scenario needs. That makes steps a deep link instead of a script.
|
|
103
195
|
|
|
104
196
|
## Selectors and checks on the UI tree
|
|
105
197
|
|
|
@@ -127,8 +219,8 @@ dialog, webview and group.
|
|
|
127
219
|
- **Pack `app` (AC7xx):** those four checks, plus a semantic question about
|
|
128
220
|
the screen's purpose and next action.
|
|
129
221
|
- **Web-only checks** (`no_overflow`, `http_status`, meta, `a11y_contrast`,
|
|
130
|
-
`perf_
|
|
131
|
-
app steps.
|
|
222
|
+
`perf_*`, `url_*`, `style_*`, `js_equals`): these are "not evaluated" on
|
|
223
|
+
app captures. Do not put them on app steps.
|
|
132
224
|
- **OCR trees:** these have text only, so role checks (labels, touch
|
|
133
225
|
targets) are not evaluated there. Say so in the report and install `idb`
|
|
134
226
|
when those checks matter.
|
|
@@ -150,7 +242,10 @@ questions about what is on the screen, not about the markup.
|
|
|
150
242
|
|
|
151
243
|
- **Devices:** never install on a person's own phone or sign in with
|
|
152
244
|
real accounts without asking. Emulators and simulators are yours to
|
|
153
|
-
start, reset and install builds on.
|
|
245
|
+
start, reset and install builds on. Dark mode and the animation scales
|
|
246
|
+
are restored after a walk, and so is the status bar of a real phone.
|
|
247
|
+
- **Windows:** clicks and typing go to the real desktop. Walk on a machine
|
|
248
|
+
nobody is using at that moment, or a CI runner.
|
|
154
249
|
- **Production apps:** production apps (store builds) are read-only in
|
|
155
250
|
spirit. Walk them only with deep links and screens that change no data,
|
|
156
251
|
unless the person agrees.
|
|
@@ -16,7 +16,9 @@ deployments; `--trigger pull_request` runs on every push instead and waits for
|
|
|
16
16
|
the deployment):
|
|
17
17
|
|
|
18
18
|
1. installs the project (`npm ci`, or pnpm, yarn, bun by the lockfile) and the
|
|
19
|
-
Chromium of kaloko's Playwright (`kaloko browser install --with-deps`)
|
|
19
|
+
Chromium of kaloko's Playwright (`kaloko browser install --with-deps`), plus
|
|
20
|
+
WebKit and Firefox when a scenario or `walk.browsers` names them
|
|
21
|
+
(`--browsers chromium,webkit`; see [devices.md](devices.md));
|
|
20
22
|
`KALOKO_BROWSER_CHANNEL=chromium` makes the run use it, so no separate CI
|
|
21
23
|
config is needed;
|
|
22
24
|
2. `kaloko ci preview-url --wait 600 --github-env` finds the preview URL, the
|
|
@@ -48,6 +48,45 @@ design/
|
|
|
48
48
|
`kaloko design lint` checks the folder; `kaloko sync` runs it first and stops on errors (things that break on
|
|
49
49
|
the live step), warnings are printed.
|
|
50
50
|
|
|
51
|
+
## Devices, dark mode and app screens
|
|
52
|
+
|
|
53
|
+
Design steps can target device presets and colour schemes like any run ([devices.md](devices.md)):
|
|
54
|
+
|
|
55
|
+
```yaml
|
|
56
|
+
# the design scenario (the same one development uses)
|
|
57
|
+
viewports: [iphone-15, pixel-8, ipad-landscape, laptop]
|
|
58
|
+
color_schemes: [light, dark]
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
- On a design environment a phone or tablet preset is the whole screen (393 × 852 on an iPhone 15), rendered with
|
|
62
|
+
the preset's touch, pixel ratio and user agent, so `(pointer: coarse)` and `(hover: none)` apply. The step detail
|
|
63
|
+
draws the device frame; *Safe areas* shows the notch, the home indicator and where the first screen ends.
|
|
64
|
+
- Dark mode: write `@media (prefers-color-scheme: dark)` in the step's CSS, and the dark captures show it. A step
|
|
65
|
+
whose dark screen is a different page gets `<step>/dark/index.html` (or `<step>/<locale>/dark/index.html`); dark
|
|
66
|
+
captures render that page, and it travels with the revision.
|
|
67
|
+
- Token modes follow the scheme: with a `theme` modifier (or `light`/`dark` groups) in the token set, Dev mode, the
|
|
68
|
+
step spec and the token check of a dark capture name the dark tokens, and drift compares dark with dark.
|
|
69
|
+
- Browsers: design steps render in Chromium. Check the implementation in WebKit and Firefox instead.
|
|
70
|
+
|
|
71
|
+
**Native app screens as portable HTML.** A mockup of an iOS or Android screen is a full-screen page:
|
|
72
|
+
|
|
73
|
+
- Size it to the screen, not to a document: `html, body { height: 100% }` and the main area `min-height: 100dvh`.
|
|
74
|
+
Do not draw the status bar or the home indicator; the frame does.
|
|
75
|
+
- Keep content out of the safe areas with
|
|
76
|
+
`padding-top: max(env(safe-area-inset-top), var(--kaloko-safe-top, 0px))` (and `-bottom`, `-left`, `-right`).
|
|
77
|
+
On the phone `env()` gives the inset; in Kaloko `--kaloko-safe-*` does, because desktop browsers report 0. Add
|
|
78
|
+
`viewport-fit=cover` to the viewport meta.
|
|
79
|
+
- Use the roles and names the app will have: `<nav aria-label="Tabs">` with buttons for a tab bar, `<header>` with
|
|
80
|
+
an `<h1>` for the navigation bar, `<button>` and labelled inputs. The step spec and the checks match the
|
|
81
|
+
implementation by role and name, and React Native `accessibilityLabel` or Android `contentDescription` are those
|
|
82
|
+
names.
|
|
83
|
+
- Touch targets of at least 44 × 44 pt (iOS) or 48 × 48 dp (Android); the app pack checks them on the real app.
|
|
84
|
+
- One design serves both platforms unless they really differ. When they do, give the platform its own scenario
|
|
85
|
+
step or its own viewport set (`viewports: [iphone-15]` in one scenario, `[pixel-8]` in another), not user-agent
|
|
86
|
+
sniffing in the page.
|
|
87
|
+
- System fonts are not portable (`-apple-system` renders differently on each machine): bundle the font the app
|
|
88
|
+
uses, as the portable HTML rules say.
|
|
89
|
+
|
|
51
90
|
## Sync and publish
|
|
52
91
|
|
|
53
92
|
- `kaloko walk` renders only revisions whose captures are missing (same files, same capture).
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# Browsers, devices, colour schemes and motion
|
|
2
|
+
|
|
3
|
+
A run captures every step in each locale and viewport. Five more dimensions can be added to that matrix: the
|
|
4
|
+
browser engine, the colour scheme, reduced motion, forced colours (Windows high contrast) and the display mode of an
|
|
5
|
+
installed web app. Viewports can name device presets instead of sizes.
|
|
6
|
+
|
|
7
|
+
## Asking for them
|
|
8
|
+
|
|
9
|
+
In the scenario, with defaults for the whole project in `walk:` of `kaloko.config.yml`, and per run on the
|
|
10
|
+
command line (the command line wins, then the scenario, then the config):
|
|
11
|
+
|
|
12
|
+
```yaml
|
|
13
|
+
# qa/flows/checkout.yml
|
|
14
|
+
viewports: [iphone-se, iphone-15, pixel-8, ipad-landscape, laptop] # presets, or { desktop: [1280, 800] } as before
|
|
15
|
+
browsers: [chromium, webkit, firefox]
|
|
16
|
+
color_schemes: [light, dark]
|
|
17
|
+
reduced_motion: [no-preference, reduce] # optional
|
|
18
|
+
forced_colors: [none, active] # optional, Windows high contrast
|
|
19
|
+
display_modes: [browser, standalone] # optional, the page as an installed PWA
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
```bash
|
|
23
|
+
npx kaloko start --scenario qa/flows/checkout.yml --env staging --browsers chromium,webkit --color-schemes light,dark
|
|
24
|
+
npx kaloko start … --viewports iphone-se,fold-open,desktop-hd # presets the scenario does not list
|
|
25
|
+
npx kaloko walk # one pass per engine and device profile
|
|
26
|
+
npx kaloko walk --browsers webkit # only the WebKit captures of the run
|
|
27
|
+
npx kaloko browser install --browsers webkit,firefox # once per machine or CI job
|
|
28
|
+
npx kaloko devices # the preset catalogue
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Every combination is one capture: `checkout × 3 viewports × 2 browsers × 2 schemes` is 12 screenshots per step and
|
|
32
|
+
locale. Keep the matrix to what the task is about. A Safari bug report needs `browsers: [chromium, webkit]` on the
|
|
33
|
+
affected steps, not every dimension on every step. A run refuses more than 400 combinations.
|
|
34
|
+
|
|
35
|
+
## Capture keys
|
|
36
|
+
|
|
37
|
+
A capture is keyed by the viewport name plus the values that differ from the default, joined by dots:
|
|
38
|
+
`mobile`, `mobile.webkit`, `iphone-15.webkit.dark`, `desktop.reduce`, `phone.standalone`. Chromium, light, no
|
|
39
|
+
motion preference, no forced colours and the browser display mode are the defaults. Runs from before these
|
|
40
|
+
dimensions have plain keys and read as Chromium. Use the keys wherever a viewport name goes: `--viewport
|
|
41
|
+
iphone-15.dark`, `capture({ viewports: ['mobile'] })` (a viewport name takes all its keys in the current pass),
|
|
42
|
+
`kaloko spec home --viewport desktop.dark`.
|
|
43
|
+
|
|
44
|
+
## Device presets
|
|
45
|
+
|
|
46
|
+
| Kind | Presets |
|
|
47
|
+
|---|---|
|
|
48
|
+
| Phones | `iphone-se` (small), `iphone-15`, `iphone-16`, `iphone-16-pro-max` (large), `pixel-8`, `pixel-8-pro`, `galaxy-s24` |
|
|
49
|
+
| Foldables | `fold-folded`, `fold-open` |
|
|
50
|
+
| Tablets | `ipad-portrait`, `ipad-landscape`, `ipad-pro-portrait`, `ipad-pro-landscape`, `android-tablet-portrait`, `android-tablet-landscape` |
|
|
51
|
+
| Computers and TV | `laptop` (1440), `desktop-hd` (1920), `desktop-wide` (2560), `tv-1080p` |
|
|
52
|
+
|
|
53
|
+
- `<preset>-landscape` turns any phone, foldable or tablet sideways (`iphone-15-landscape`).
|
|
54
|
+
- A preset sets the CSS viewport, the pixel ratio, mobile mode, touch and the device's user agent. Web walks get
|
|
55
|
+
the screen minus the browser's bars (393 × 659 on an iPhone 15 in Safari); Design environments and installed
|
|
56
|
+
PWAs get the whole screen (393 × 852).
|
|
57
|
+
- Overrides: `{ phone: { device: iphone-15, height: 700 } }`, or `full_screen: true` for a kiosk or an app mockup.
|
|
58
|
+
- Screenshots stay in CSS pixels whatever the pixel ratio, so boxes, diffs and comments line up across devices.
|
|
59
|
+
- The values are those of the device class, not of a lab. They catch layout bugs; a real device catches the rest.
|
|
60
|
+
|
|
61
|
+
## How each dimension is produced
|
|
62
|
+
|
|
63
|
+
| Dimension | How | Engines |
|
|
64
|
+
|---|---|---|
|
|
65
|
+
| Browser | Playwright's Chromium, WebKit (Safari's engine) and Firefox, each in its own pass | all |
|
|
66
|
+
| Device preset | its own browser context with the pixel ratio, mobile mode, touch and user agent | all; Firefox has no mobile mode, so presets there set size, ratio, touch and agent |
|
|
67
|
+
| Colour scheme, reduced motion, forced colours | `prefers-color-scheme`, `prefers-reduced-motion` and `forced-colors` emulated per capture | all |
|
|
68
|
+
| Display mode | `display-mode` media rules of same-origin style sheets and `matchMedia` answered as installed; full-screen size | all |
|
|
69
|
+
|
|
70
|
+
- Scripts that read `matchMedia('(display-mode: standalone)')` once at load still see the browser mode; CSS and
|
|
71
|
+
later calls see the installed mode. Check `navigator.standalone`-style logic on a real install.
|
|
72
|
+
- The shared browser (Chromium over CDP) walks the default pass; WebKit, Firefox and device profiles always get
|
|
73
|
+
their own context, signed in through the scenario's sessions as usual.
|
|
74
|
+
- E-mail steps are captured once, in the first pass.
|
|
75
|
+
|
|
76
|
+
## Checks that only Chromium can run
|
|
77
|
+
|
|
78
|
+
These are "not evaluated" on WebKit and Firefox captures, with the reason, and do not make a step partial when
|
|
79
|
+
Chromium evaluated them:
|
|
80
|
+
|
|
81
|
+
- `a11y_ax_names` (the accessibility tree is read over the DevTools protocol);
|
|
82
|
+
- `a11y_focus_visible` (focus rings are compared on Chromium screenshots);
|
|
83
|
+
- `perf_cls` (only Chromium reports layout shifts);
|
|
84
|
+
- on WebKit also the Tab walk (`a11y_focus_order`, `a11y_keyboard_trap`, `a11y_skip_link`): WebKit moves Tab
|
|
85
|
+
between form controls only, like Safari by default, so the walk would report false gaps.
|
|
86
|
+
|
|
87
|
+
Everything else (DOM checks, contrast, overflow, links, LCP, TTFB, weight, semantic and vision criteria) runs on
|
|
88
|
+
every engine. Contrast is checked per colour scheme, so a dark-mode contrast bug fails on the `.dark` capture.
|
|
89
|
+
|
|
90
|
+
Semantic questions read the page text: the same text in another engine or scheme is the same question, answered
|
|
91
|
+
once and then from the cache. Vision questions (`vision: true`) look at each screenshot, so every combination is
|
|
92
|
+
asked separately; keep `vision: true` to the steps where the look is the point.
|
|
93
|
+
|
|
94
|
+
## On the canvas
|
|
95
|
+
|
|
96
|
+
- Switchers for the browser, colour scheme, motion, forced colours and display mode sit next to the locale in the
|
|
97
|
+
top bar and in review mode. The map, the index, the step detail and review show the chosen combination.
|
|
98
|
+
With more than five values (20 locales, say) a switcher is a button that opens a searchable list with the
|
|
99
|
+
status of each value; `L` opens the locale list, `[` and `]` move to the previous and next locale.
|
|
100
|
+
- The step detail of a device preset draws its frame: bezel, status bar, the browser's bars and the island, notch
|
|
101
|
+
or camera. *Safe areas* marks the insets and where the first screen ends. Both can be switched off.
|
|
102
|
+
- *Beside* puts the same step in another browser or scheme next to it (WebKit beside Chromium, dark beside light).
|
|
103
|
+
- Links keep the key (`#step=cart&vp=iphone-15.webkit.dark`) and switch the canvas to it.
|
|
104
|
+
|
|
105
|
+
## Doctor and CI
|
|
106
|
+
|
|
107
|
+
`kaloko doctor` lists the engines the scenarios and `walk.browsers` name and says how to install a missing one.
|
|
108
|
+
In CI install them in the job: `npx kaloko browser install --browsers chromium,webkit --with-deps` (Linux needs
|
|
109
|
+
the system libraries WebKit and Firefox bring).
|
|
@@ -18,6 +18,12 @@ environment whose URL comes from CI: `preview: { base_url: ${KALOKO_PREVIEW_URL}
|
|
|
18
18
|
which `kaloko ci github|gitlab` adds and `kaloko ci preview-url` fills; see
|
|
19
19
|
[ci.md](ci.md).
|
|
20
20
|
|
|
21
|
+
An environment says where the product runs. In which browsers, on which devices and in which colour scheme it is
|
|
22
|
+
walked is the run's matrix: `browsers`, `color_schemes`, `reduced_motion` and device presets in `viewports` of the
|
|
23
|
+
scenario, defaults in `walk:` of the config, `--browsers` and friends on `kaloko start`; see
|
|
24
|
+
[devices.md](devices.md). App devices (emulators, simulators, phones) are named per environment under
|
|
25
|
+
`app.<platform>.devices`; see [apps.md](apps.md).
|
|
26
|
+
|
|
21
27
|
## Who does what
|
|
22
28
|
|
|
23
29
|
Kaloko needs evidence in its format: captures of screens and e-mails in a run.
|
|
@@ -41,6 +41,12 @@ call `kaloko session reset` themselves when the plan starts as a new visitor.
|
|
|
41
41
|
Prefer turning an agent step into a playwright script once it has worked
|
|
42
42
|
twice the same way.
|
|
43
43
|
|
|
44
|
+
A step script brings the page into the state the step accepts; it does not
|
|
45
|
+
check it. Do not compute a result in the script and write a `data-qa-*`
|
|
46
|
+
marker into the page for a criterion to find. The URL, computed styles and
|
|
47
|
+
values in the page have their own checks (`url_matches`, `style_equals`,
|
|
48
|
+
`js_equals`; see [acceptance.md](acceptance.md#url-computed-styles-and-values-in-the-page)).
|
|
49
|
+
|
|
44
50
|
## Driving the shared browser with your capabilities
|
|
45
51
|
|
|
46
52
|
- Browser tool over MCP (e.g. Playwright MCP): connect to the CDP endpoint
|