Skip to content

Commit 628af4c

Browse files
committed
Fix matrix test failures
1 parent 6f085ae commit 628af4c

30 files changed

Lines changed: 1889 additions & 557 deletions

DOCUMENTATION.md

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,9 @@ const std = @import("std");
1919
const driver = @import("alldriver");
2020
2121
pub fn run(allocator: std.mem.Allocator) !void {
22-
var installs = try driver.modern.discover(allocator, .{
22+
var session = try driver.modern.launchAuto(allocator, .{
2323
.kinds = &.{ .chrome, .firefox, .lightpanda },
2424
.allow_managed_download = false,
25-
}, .{});
26-
defer installs.deinit();
27-
28-
if (installs.items.len == 0) return error.NoBrowserFound;
29-
30-
var session = try driver.modern.launch(allocator, .{
31-
.install = installs.items[0],
3225
.profile_mode = .ephemeral,
3326
.headless = true,
3427
});
@@ -47,10 +40,12 @@ pub fn run(allocator: std.mem.Allocator) !void {
4740
- `discover(...) -> BrowserInstallList`
4841
- `discoverWebViews(...) -> WebViewRuntimeList`
4942
- Caller owns the returned lists and must call `.deinit()`.
43+
- `launchAuto(...)` / `launchAutoAsync(...)` run discovery with sane defaults and return a fully ready session.
5044

5145
### Modern session domains
5246

5347
- `page()`, `runtime()`, `network()`, `input()`, `log()`, `storage()`, `contexts()`, `targets()`
48+
- `launch`, `launchAuto`, `attach`, and webview attach/launch all wait for protocol readiness; no manual CDP/BiDi session bootstrap is required.
5449

5550
### Waits and cancellation
5651

README.md

Lines changed: 110 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,36 @@
1-
# alldriver
1+
# 🚀 alldriver
22

3-
> Modern browser automation for Zig using CDP and BiDi.
3+
Modern browser automation for Zig with a CDP/BiDi-first API, deterministic discovery, and production gates.
44

5-
[![zig](https://img.shields.io/badge/Zig-0.15.x-orange)](#)
6-
[![platforms](https://img.shields.io/badge/Platforms-Windows%20%7C%20macOS%20%7C%20Linux-blue)](#)
7-
[![protocols](https://img.shields.io/badge/Protocols-CDP%20%7C%20BiDi-green)](#)
5+
![Zig](https://img.shields.io/badge/Zig-0.15.x-f7a41d?logo=zig&logoColor=111)
6+
![Platforms](https://img.shields.io/badge/Platforms-Windows%20%7C%20macOS%20%7C%20Linux-2ea44f)
7+
![Protocols](https://img.shields.io/badge/Protocols-CDP%20%7C%20BiDi-0366d6)
8+
![API](https://img.shields.io/badge/API-modern-0f766e)
89

9-
`alldriver` is a library-first automation framework focused on real browser binaries, deterministic discovery, and typed behavior.
10+
## ⚡ Features
1011

11-
## Why
12+
- CDP/BiDi-first modern API (`driver.modern.*`) with typed domain clients.
13+
- Auto-launch and auto-attach flows that wait for real protocol readiness.
14+
- Deterministic browser discovery (PATH + known paths + OS probes + managed cache).
15+
- Typed waits, cancellation tokens, lifecycle events, timeout policies, diagnostics.
16+
- Typed cookie query/export helpers and built-in session cache.
17+
- Runtime Lightpanda download/install support (no build-time dependency).
18+
- Production tooling: adversarial detection gate, matrix, release bundle.
1219

13-
- CDP/BiDi-first API with typed domain clients.
14-
- Deterministic browser/webview discovery across desktop platforms.
15-
- Strong capability and error contracts (explicit unsupported behavior).
16-
- Built-in adversarial, matrix, and GA tooling.
17-
18-
## Safety Boundary
19-
20-
`alldriver` is for standards-compliant automation (testing, QA, scripting).
21-
It does **not** include detection-bypass/evasion primitives.
22-
23-
## Install
24-
25-
```bash
26-
zig fetch --save git+https://github.com/SmallThingz/alldriver
27-
```
28-
29-
Then import in `build.zig.zon` and `build.zig` as usual for Zig dependencies.
30-
31-
## Quick Start
20+
## 🚀 Quick Start
3221

3322
```zig
3423
const std = @import("std");
3524
const driver = @import("alldriver");
3625
37-
pub fn run(allocator: std.mem.Allocator) !void {
38-
var installs = try driver.modern.discover(allocator, .{
26+
pub fn main() !void {
27+
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
28+
defer _ = gpa.deinit();
29+
const allocator = gpa.allocator();
30+
31+
var session = try driver.modern.launchAuto(allocator, .{
3932
.kinds = &.{ .chrome, .firefox, .lightpanda },
4033
.allow_managed_download = false,
41-
}, .{});
42-
defer installs.deinit();
43-
44-
if (installs.items.len == 0) return error.NoBrowserFound;
45-
46-
var session = try driver.modern.launch(allocator, .{
47-
.install = installs.items[0],
4834
.profile_mode = .ephemeral,
4935
.headless = true,
5036
});
@@ -56,135 +42,140 @@ pub fn run(allocator: std.mem.Allocator) !void {
5642
}
5743
```
5844

59-
## API At A Glance
60-
61-
### Discovery ownership
62-
63-
- `discover(...) -> BrowserInstallList`
64-
- `discoverWebViews(...) -> WebViewRuntimeList`
65-
- Caller owns memory and must call `.deinit()`.
66-
67-
### Modern session domains
45+
## 📦 Install
6846

69-
- `page()`, `runtime()`, `network()`, `input()`, `log()`, `storage()`, `contexts()`, `targets()`
70-
71-
### Waits and cancellation
72-
73-
- `waitFor(target, opts)` + `waitForAsync(target, opts)`
74-
- Targets: `dom_ready`, `network_idle`, `selector_visible`, `url_contains`, `cookie_present`, `storage_key_present`, `js_truthy`
75-
- `CancelToken` for cooperative cancel.
76-
77-
### Events
47+
```bash
48+
zig fetch --save git+https://github.com/SmallThingz/alldriver
49+
```
7850

79-
- `onEvent(filter, callback)` / `offEvent(id)`
80-
- Event kinds: `navigation_started`, `navigation_completed`, `challenge_detected`, `challenge_solved`, `cookie_updated`
51+
Then add the dependency import in your `build.zig` as usual.
8152

82-
### Timeouts and diagnostics
53+
## 🧠 API At A Glance
8354

84-
- `setTimeoutPolicy`, `timeoutPolicy`, `lastDiagnostic`
85-
- `setHardErrorLogger` (global hard-error callback; defaults to stderr if unset)
55+
### Modern surface
8656

87-
### Cookie helpers
57+
- `driver.modern.discover(...)`
58+
- `driver.modern.launch(...)`
59+
- `driver.modern.launchAuto(...)`
60+
- `driver.modern.attach(...)`
8861

89-
- `queryCookies`
90-
- `buildCookieHeaderForUrl`
62+
### Session domains
9163

92-
### Session cache
64+
- `session.page()`
65+
- `session.runtime()`
66+
- `session.network()`
67+
- `session.input()`
68+
- `session.log()`
69+
- `session.storage()`
70+
- `session.contexts()`
71+
- `session.targets()`
9372

94-
- `SessionCacheStore.open/load/save/saveWithOptions/invalidate/cleanupExpired`
95-
- Payload presets:
96-
- `.minimal` (cookies)
97-
- `.http_session` (cookies + user agent)
98-
- `.rich_state` (cookies + user agent + storage + url + extra headers)
99-
- Custom combinations via `SessionCachePayloadMask`.
73+
### Waits, cancel, events
10074

101-
### Runtime Lightpanda Download
75+
- `session.waitFor(target, opts)`
76+
- `session.waitForAsync(target, opts)`
77+
- `driver.CancelToken`
78+
- `session.onEvent(filter, callback)` / `session.offEvent(id)`
10279

103-
- Runtime API: `driver.lightpanda.downloadLatest(allocator, .{ .cache_dir = null, .tag = null })`
104-
- Tools command: `zig build tools -- download-lightpanda`
80+
### Timeout + diagnostics
10581

106-
## Coverage
82+
- `session.setTimeoutPolicy(...)`
83+
- `session.timeoutPolicy()`
84+
- `session.lastDiagnostic()`
85+
- `driver.modern.setHardErrorLogger(...)`
10786

108-
### Modern (supported)
87+
### Cookie/session utilities
10988

110-
- Chromium-family browsers via CDP
111-
- Firefox/Gecko via BiDi
112-
- CDP-capable webviews: `webview2`, `electron`, `android_webview`
89+
- `session.storage().queryCookies(...)`
90+
- `session.storage().buildCookieHeaderForUrl(...)`
91+
- `driver.SessionCacheStore.open/load/save/saveWithOptions/invalidate/cleanupExpired`
11392

114-
### Unsupported tier (discovered/classified, not driven)
93+
## 🌐 Coverage
11594

116-
- Targets without usable CDP/BiDi surfaces on the host.
95+
### Modern supported
11796

118-
## Runtime Notes
97+
- Chromium-family browsers via CDP.
98+
- Firefox/Gecko via BiDi.
99+
- CDP-capable webviews: `webview2`, `electron`, `android_webview`.
119100

120-
- Launch now blocks until the local debug endpoint is reachable (bounded by launch timeout policy) to reduce race-condition `ConnectionRefused` failures in immediate post-launch actions.
121-
- Deprecated launch compatibility flag `legacy_automation_markers` has been removed from public options.
101+
### Unsupported tier
122102

123-
## External Binary Dependencies
103+
- Targets without usable CDP/BiDi surfaces on the host are discovered/classified but not driven.
124104

125-
### Core runtime
105+
## 💾 Managed Browser Cache
126106

127-
- Browser binaries (at least one target installed): Chrome/Chromium, Edge, Firefox, Brave, Tor Browser, DuckDuckGo Browser, Mullvad Browser, LibreWolf, Epic, Arc, Vivaldi, SigmaOS, Sidekick, Shift, Opera GX, Pale Moon.
128-
- Optional Lightpanda binary can be installed at runtime via `driver.lightpanda.downloadLatest(...)` (GitHub release assets).
129-
- Webview/runtime binaries as applicable: `msedgewebview2`, `electron`.
130-
- Mobile bridge tooling: `adb`, `shizuku` (or `rish`) for Android WebView.
107+
When `managed_cache_dir` is unset, default paths are:
131108

132-
Managed browser cache defaults (used when `managed_cache_dir` is unset):
133109
- Linux: `$XDG_CACHE_HOME/alldriver/browsers` (fallback `$HOME/.cache/alldriver/browsers`)
134110
- macOS: `$HOME/Library/Caches/alldriver/browsers`
135111
- Windows: `%LOCALAPPDATA%\\alldriver\\browsers`
136112

137-
`discover()` always scans managed cache. `allow_managed_download` controls provisioning/download permission, not cache discovery.
113+
`discover()` always scans managed cache.
114+
`allow_managed_download` controls whether provisioning/download is allowed.
115+
116+
## 🐼 Lightpanda Runtime Download
138117

139-
### Tooling / matrix / release (`zig build tools -- ...`)
118+
Programmatic:
140119

141-
- Base tooling: `zig`, `git`, `bash`, `tar`, `date`, `which` (or `where` on Windows), `chmod`.
142-
- Signing: `gpg`.
143-
- Remote orchestration: `ssh`, `scp`, `rsync`.
144-
- VM/QEMU workflows: `qemu-system-x86_64`, `qemu-img`, `curl`, `ssh-keygen`.
145-
- Optional checksum verification: `sha256sum`.
120+
```zig
121+
const installed = try driver.modern.downloadLightpandaLatest(allocator, .{
122+
.cache_dir = null,
123+
.tag = null,
124+
.expected_sha256_hex = null,
125+
});
126+
defer allocator.free(installed);
127+
```
128+
129+
Tooling:
130+
131+
```bash
132+
zig build tools -- download-lightpanda
133+
```
146134

147-
## Common Commands
135+
## 🧪 Build / Test / Gates
148136

149137
```bash
150-
# Build + tests
138+
# core
151139
zig build test
152140
zig build examples
141+
zig build run
153142

154-
# Opt-in live adversarial check for flatmates.com.au (fails on 429/challenge facade)
155-
ALLDRIVER_ADVERSARIAL_FLATMATES=1 zig build test --summary all
156-
157-
# Tool self-check
143+
# tool sanity
158144
zig build tools -- self-test
159145

160-
# Gates
146+
# adversarial gate
161147
zig build tools -- adversarial-detection-gate --allow-missing-browser=1
148+
149+
# production gate
162150
zig build production-gate
163151
zig build tools -- production-gate --strict-ga
152+
```
164153

165-
# Matrix + release
166-
zig build tools -- matrix-run --platform linux
167-
zig build tools -- matrix-collect
168-
zig build tools -- release-bundle --release-id v1.0.0
154+
## 🧰 External Binaries
169155

170-
# Runtime browser provisioning
171-
zig build tools -- download-lightpanda
156+
### Core runtime (library users)
172157

173-
# VM / QEMU helpers
174-
zig build tools -- vm-check-prereqs
175-
zig build tools -- vm-image-sources --check
176-
zig build tools -- vm-init-lab --project alldriver
177-
zig build tools -- vm-create-linux --project alldriver --name linux-matrix
178-
zig build tools -- vm-start-linux --project alldriver --name linux-matrix
179-
zig build tools -- vm-run-linux-matrix --project alldriver --name linux-matrix
180-
```
158+
- Browser binaries for your chosen targets (Chrome/Edge/Firefox/Brave/etc.).
159+
- Optional Lightpanda binary (auto-downloaded at runtime if requested).
160+
- Optional webview runtimes/tools when using those flows (`msedgewebview2`, `electron`, Android bridge tools such as `adb` or `shizuku`/`rish`).
161+
162+
If you only use `discover/launch/attach` against installed desktop browsers, no additional tooling binaries are required by the library core.
163+
164+
### Tooling/matrix/release (`zig build tools -- ...`)
165+
166+
- `git`, `bash`, `tar`, `date`, `which`/`where`, `chmod`
167+
- `gpg` (sign/verify)
168+
- `ssh`, `scp`, `rsync` (remote matrix)
169+
- `qemu-system-x86_64`, `qemu-img`, `curl`, `ssh-keygen` (VM workflows)
181170

182-
## Examples
171+
## 🛡 Safety Boundary
183172

184-
See `/home/a/projects/zig/browser_driver/examples/README.md` for runnable examples.
173+
`alldriver` is for standards-compliant automation (QA/testing/scripting).
174+
It does **not** provide built-in detection-bypass/evasion primitives.
185175

186-
## Docs
176+
## 📚 Documentation
187177

188178
- `/home/a/projects/zig/browser_driver/DOCUMENTATION.md`
179+
- `/home/a/projects/zig/browser_driver/examples/README.md`
189180
- `/home/a/projects/zig/browser_driver/CONTRIBUTING.md`
190181
- `/home/a/projects/zig/browser_driver/SECURITY.md`

build.zig

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,30 @@ pub fn build(b: *std.Build) void {
207207
// A run step that will run the test executable.
208208
const run_mod_tests = b.addRunArtifact(mod_tests);
209209

210+
const platform_tests = b.addTest(.{
211+
.root_module = b.createModule(.{
212+
.root_source_file = b.path("src/platform_matrix_runner.zig"),
213+
.target = target,
214+
.optimize = optimize,
215+
.imports = &.{
216+
.{ .name = "alldriver_config", .module = config.createModule() },
217+
},
218+
}),
219+
});
220+
const run_platform_tests = b.addRunArtifact(platform_tests);
221+
222+
const behavioral_tests = b.addTest(.{
223+
.root_module = b.createModule(.{
224+
.root_source_file = b.path("src/behavioral_matrix_runner.zig"),
225+
.target = target,
226+
.optimize = optimize,
227+
.imports = &.{
228+
.{ .name = "alldriver_config", .module = config.createModule() },
229+
},
230+
}),
231+
});
232+
const run_behavioral_tests = b.addRunArtifact(behavioral_tests);
233+
210234
// Creates an executable that will run `test` blocks from the executable's
211235
// root module. Note that test executables only test one module at a time,
212236
// hence why we have to create two separate ones.
@@ -227,6 +251,8 @@ pub fn build(b: *std.Build) void {
227251
// make the two of them run in parallel.
228252
const test_step = b.step("test", "Run tests");
229253
test_step.dependOn(&run_mod_tests.step);
254+
test_step.dependOn(&run_platform_tests.step);
255+
test_step.dependOn(&run_behavioral_tests.step);
230256
test_step.dependOn(&run_exe_tests.step);
231257
test_step.dependOn(&run_tools_tests.step);
232258

examples/02_launch_and_navigate.zig

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6,22 +6,11 @@ pub fn main() !void {
66
defer _ = gpa_state.deinit();
77
const allocator = gpa_state.allocator();
88

9-
var installs = try driver.discover(allocator, .{
10-
.kinds = &.{ .chrome, .edge, .firefox },
9+
var launch_op = try driver.modern.launchAutoAsync(allocator, .{
10+
.kinds = &.{ .chrome, .edge, .firefox, .lightpanda },
1111
.allow_managed_download = false,
12-
}, .{});
13-
defer installs.deinit();
14-
15-
if (installs.items.len == 0) {
16-
std.debug.print("no browser install found\n", .{});
17-
return;
18-
}
19-
20-
var launch_op = try driver.modern.launchAsync(allocator, .{
21-
.install = installs.items[0],
2212
.profile_mode = .ephemeral,
2313
.headless = true,
24-
.args = &.{},
2514
});
2615
defer launch_op.deinit();
2716
var session = try launch_op.await(30_000);

0 commit comments

Comments
 (0)