Architecture
NATL separates what to test (YAML scenarios) from how the browser is driven (adapters). Typical UI flows stay portable when you change engine:.
Packages
flowchart LR
YAML["YAML scenarios"] --> CLI["@natl/cli"]
CLI --> Core["@natl/core"]
Core --> Adapters["UI adapters"]
Core --> HTTP["built-in http"]
Adapters --> PW["Playwright"]
Adapters --> SE["Selenium"]
Adapters --> CY["Cypress"]
- @natl/cli — finds files, loads config, filters tags, loads the adapter
- @natl/core — parse, interpolate, interpret; no browser dependency
- Adapters — Playwright / Selenium / Cypress as separate packages
- http — built into core for API-only or
with: httpblocks
Run path
flowchart TB
Run["natl run"] --> Config["Config + YAML"]
Config --> Parse["Parse + interpolate"]
Parse --> Interp["Interpreter"]
Interp --> Choice{"engine"}
Choice -->|"playwright / selenium / cypress"| UI["UI adapter"]
Choice -->|"http"| Fetch["HTTP fetch"]
Browsers and driver details stay in the adapter. Core passes opaque options like browser and viewport from natl.config.yaml. More design rules: Canon.