Skip to content

Commit 894a9b9

Browse files
titusfortnerdiemol
andauthored
[adr] BiDi implementation boundaries (#17670)
* [docs] add design decision record process and template * [adr] BiDi is an implementation mechanism, not a public API * add examples with details as requested * [adr] rework BiDi record: number by PR, drop index, reframe table and examples * [docs] ADR 17670: BiDi implementation boundaries — supported API vs internal, composition access --------- Co-authored-by: Diego Molina <diemol@users.noreply.github.com>
1 parent 97373d2 commit 894a9b9

1 file changed

Lines changed: 70 additions & 0 deletions

File tree

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
# 17670. BiDi implementation boundaries
2+
3+
- Status: Proposed
4+
- Discussion: https://github.com/SeleniumHQ/selenium/pull/17670
5+
6+
## Context
7+
8+
Bindings use WebDriver BiDi to implement and extend the Selenium API. This record settles what
9+
users program against: where the supported API ends and the internal BiDi implementation begins.
10+
11+
No binding conforms yet: each exposes BiDi implementation details from the driver object rather
12+
than keeping them internal.
13+
14+
| Binding | Current behavior |
15+
|------------|------------------|
16+
| Java | Driver exposes the raw BiDi connection (`HasBiDi.getBiDi()`); protocol types are public |
17+
| Python | `driver.network` / `driver.script` are the right high-level names, but return the low-level BiDi modules (`bidi`-namespaced) instead of neutral wrappers |
18+
| Ruby | Driver exposes a BiDi accessor (`driver.bidi`) |
19+
| .NET | Driver extension returns a BiDi type (`AsBiDiAsync()``IBiDi`) |
20+
| JavaScript | Driver exposes a BiDi accessor (`driver.getBidi()`) |
21+
22+
All bindings also expose a BiDi-named option to enable the session (`enableBiDi` / `enable_bidi`),
23+
which can be renamed to be protocol-neutral.
24+
25+
## Decision
26+
27+
BiDi is an implementation mechanism, not a public API. Three decisions follow:
28+
29+
1. **The supported API is protocol-neutral.** It never references BiDi — no BiDi types, and
30+
nothing that hands a user a BiDi object. Users program against the Selenium API and its
31+
high-level APIs, under the deprecation policy.
32+
2. **The BiDi implementation is internal and unsupported.** It faithfully implements the
33+
commands, events, and modules of the BiDi spec (and could be generated from the CDDL). It
34+
stays publicly reachable but is not governed by the deprecation policy: the spec is written to
35+
be stable, but because it is not ours we do not guarantee it. Each binding marks it internal
36+
by its own convention.
37+
3. **Low-level access is by composition, never off the driver.** The implementation is reached
38+
by composing it with the driver — `BiDi::Protocol::Network.new(driver)` — never exposed as a
39+
member of the driver, because anything reachable off the driver reads implicitly as supported.
40+
41+
Everything else — orchestration, event dispatch, socket listening, transport — is an
42+
implementation detail, likely private, left to each binding.
43+
44+
Marking a surface *Beta* does not satisfy decision 2 — Beta signals an API becoming supported,
45+
the opposite of internal.
46+
47+
Illustratively (Ruby):
48+
49+
```ruby
50+
driver.network.add_request_handler(...) # supported — neutral, returns no BiDi type
51+
BiDi::Protocol::Network.new(driver).add_intercept(...) # internal — composed with the driver, unsupported
52+
driver.bidi.network.add_intercept(...) # not allowed — internal exposed as a driver member
53+
```
54+
55+
## Considered options
56+
57+
1. Expose the whole protocol as a public API (Rejected)
58+
* the internal layer faithfully implements a living spec, so we cannot guarantee its stability — it can't be committed to as supported, public API
59+
2. A supported, separate "mid-level" API for working with the internal BiDi implementation (Rejected)
60+
* protocol coupling — users build on BiDi-shaped concepts, the same trap CDP created
61+
* two supported surfaces — a protocol-neutral high-level one and a BiDi-shaped mid-level one — leave users unsure which to reach for
62+
3. Expose the internal implementation as a driver member, e.g. `driver.bidi.network` (Rejected)
63+
* a member of the driver reads implicitly as supported; composing the class with the driver instead keeps it distinct
64+
4. Internal implementation mechanism only, reached by composing with the driver (Accepted)
65+
66+
## Consequences
67+
68+
- Users never need to know which protocol services a command.
69+
- Existing public surfaces that fail conformance are brought in line per the deprecation policy.
70+
- Specific supported API behavior is specified in other ADRs.

0 commit comments

Comments
 (0)