The remote debugger ships prebuilt Selenium-style JavaScript atoms
under the atoms/ directory — small bundled scripts (click.js, get_text.js, is_displayed.js,
...) that get injected into the page over the WebKit Web Inspector protocol.
Upstream Selenium's JS atoms are effectively unmaintained, so this package does not sync from
upstream. atoms/src/ is hand-written TypeScript that this package owns and maintains directly
(see atoms/src/README.md for the source layout) — there is no Bazel
dependency, no Selenium clone step, and no periodic "refresh from trunk" workflow.
| Path | Contents |
|---|---|
atoms/src/ |
Hand-written TypeScript source — see atoms/src/README.md. |
atoms/src/entrypoints/*.ts |
One file per atom; each re-exports the real implementation as its default export. |
atoms/*.js |
Bundled output — what lib/atoms.ts actually loads at runtime. Committed to git. |
atoms/src/entrypoints/automation/*.ts |
Same idea, for the separate automation-atom set below. |
atoms/automation/*.js |
Bundled output for that set — what lib/rpc/automation/atoms.ts loads. Committed to git. |
scripts/build-atoms.mjs |
The bundler script (Node.js + esbuild) - builds both sets. |
This package actually ships two differently-shaped atom sets, built by the same script:
atoms/*.js(ATOM_NAMESinlib/atoms.ts) - the classic WebDriver-wire-protocol atoms, injected viaRuntime.evaluate(executeAtom). Their entry points take{ELEMENT}-wrapped element args and return a JSON-stringified{status, value}response, becauseRuntime.evaluatehas no way to resolve/serialize DOM nodes itself.atoms/automation/*.js(AUTOMATION_ATOM_NAMESinlib/rpc/automation/atoms.ts) - used by the WebKitAutomation-domain session (lib/rpc/automation/, see its own module docs). WebKit'sAutomation.evaluateJavaScriptFunctionresolves element arguments and JSON-serializes return values itself, so these entry points take/return plain values directly - no wire-protocol layer. Both sets reuse the sameatoms/src/core//atoms/src/webdriver/implementations; only the entry-point layer differs. This set'sAUTOMATION_OUTPUT_WRAPPER(scripts/build-atoms.mjs) also catches a thrownBotErrorand re-throws its W3Cstate/messageas JSON, since WebKit only relays a thrown error's.messageback to Node -lib/rpc/automation/errors.tsrecovers the precise W3C error from that on the other side (see its own module docs).
npm run build:atomsThis runs scripts/build-atoms.mjs, which bundles each entry point under atoms/src/entrypoints/
(and atoms/src/entrypoints/automation/) with esbuild (minified, IIFE format) and writes the
result to atoms/<name>.js (or atoms/automation/<name>.js), wrapped so the file's content is a
single callable-function expression. Only mobile Safari is targeted — this package doesn't need
to (and doesn't) support other browsers.
- Edit the relevant file(s) under
atoms/src/core/oratoms/src/webdriver/. - If you're adding a brand-new atom (not just editing an existing one):
- Add an entry point file under
atoms/src/entrypoints/<name>.ts(oratoms/src/entrypoints/automation/<name>.tsfor the automation set) that re-exports the implementation as its default export, e.g.export {myFunction as default} from '../core/my-module.js';. - Add
'<name>'to theATOMSarray (orAUTOMATION_ATOMSarray) inscripts/build-atoms.mjs, and toATOM_NAMESinlib/atoms.ts(orAUTOMATION_ATOM_NAMESinlib/rpc/automation/atoms.ts).
- Add an entry point file under
- Run
npm run typecheck:atoms, thennpm run build:atomsand commit both theatoms/src/change and the regeneratedatoms/*.js/atoms/automation/*.jsoutput together. - Run the tests (below).
test/unit/atoms.spec.ts— jsdom-backed green-path tests that exercise every compiled atom directly (locators, element state, interaction, frames, storage, script execution, HTML5 storage/geolocation, and the element cache). Runs as part ofnpm teston every push/PR, no simulator needed.test/functional/atoms-e2e.spec.ts— a smaller set of the same atom families exercised against a real Safari session in an iOS Simulator. Runs vianpm run e2e-test:atoms/verify-atoms.yml'se2ejob (only when atoms change, see below). Shares its simulator/RemoteDebugger setup withsafari-e2e.spec.tsbelow viatest/functional/rd-fixture.ts.test/functional/safari-e2e.spec.ts— the rest of the functional suite (connection handling, network/console event capture, screenshots, shadow DOM), unrelated to atoms specifically. Runs vianpm run e2e-test/ thefunctional-test.ymlCI workflow on every PR. Its Automation-session test exercises the automation atom set end to end.test/unit/rpc/automation/atoms-loader.spec.ts— the automation-atom-set equivalent oftest/unit/atoms-loader.spec.ts(guardslib/atoms.ts'sATOM_NAMESagainst drift from the committedatoms/*.jsfiles): guardsAUTOMATION_ATOM_NAMESagainst drift from the committedatoms/automation/*.jsfiles, and exercisesgetAutomationAtomScript's load/cache path.
verify-atoms.yml only triggers when the diff touches atoms/**, scripts/build-atoms.mjs, or
package.json (via on.push.paths/on.pull_request.paths) — for any other PR it doesn't run at
all.
verify-atomsexecutesnpm run build:atomsand fails the build if the regeneratedatoms/differs from what's committed, soatoms/src/andatoms/*.jscan never silently drift apart.e2eruns the same iOS Simulator matrix asfunctional-test.yml, but onlytest/functional/atoms-e2e.spec.ts(vianpm run e2e-test:atoms), so an atoms change also gets verified against a real Safari session before merge, without duplicating the rest offunctional-test.yml's suite.