Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 43 additions & 0 deletions .github/ISSUE_TEMPLATE/adr-tracking.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: 📋 ADR Implementation Tracking
description: Track per-binding convergence on an accepted design decision record (ADR)
title: "[📋 ADR]: "
body:
- type: markdown
attributes:
value: |
Open this issue when a design decision record is **Accepted**. It tracks each binding's
progress toward implementing the decision so the committed record stays immutable.
Link it from the record's PR. See [docs/decisions/README.md](https://github.com/SeleniumHQ/selenium/blob/trunk/docs/decisions/README.md).

- type: input
id: record
attributes:
label: Decision record
description: Link to the accepted record and its PR (the record number is the PR number).
placeholder: "docs/decisions/NNNN-title.md (#NNNN)"
validations:
required: true

- type: textarea
id: bindings
attributes:
label: Binding implementation
description: |
Replace each placeholder with the implementing PR and check the box when it merges.
Mark a binding `n/a` with a note if the decision does not apply to it.
value: |
- [ ] Java — _PR_
- [ ] Python — _PR_
- [ ] Ruby — _PR_
- [ ] .NET — _PR_
- [ ] JavaScript — _PR_
validations:
required: true

- type: textarea
id: notes
attributes:
label: Notes
description: Anything blocking convergence, or per-binding caveats discovered during implementation.
validations:
required: false
26 changes: 26 additions & 0 deletions .github/PULL_REQUEST_TEMPLATE/adr.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<!-- Proposing an ADR (see docs/decisions/README.md). Don't restate the decision here; keep this
body to proposal notes and review logistics. Rename the record file to NNNN-short-title.md
using this PR's number before merge. -->

📄 The decision, its rationale, considered options, and consequences are in the record file
this PR adds; read it there. The sections below are proposal notes and review logistics.

### 🔗 Related

<!-- Link any ADRs this depends on, builds on, competes with, or supersedes; reference
implementations or code PRs; and prior discussions or design docs. Omit if none. -->

### 📝 Proposal notes

<!-- Notes about the proposal, not the decision: why these choices are grouped into one record,
what is deliberately deferred or out of scope, and any follow-on proposals. -->

### 🗣 Discussion

<!-- Open questions you'd like reviewers or the TLC to weigh in on (frame them as questions for
input, not as defects), and the outcome of the TLC meeting(s) where this was discussed. -->

### 📌 Tracking

<!-- Filled in on acceptance: open the ADR tracking issue and link it here. -->
Tracking issue: _(linked on acceptance)_
50 changes: 28 additions & 22 deletions docs/decisions/0000-template.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
# NNNN. Title stating the decision as a fact

<!-- Good: "Clicks scroll elements into view before interacting"
Bad: "Click behavior" -->
<!-- NNNN is this proposal's PR number. Good title: "Clicks scroll elements into view before
interacting"; bad: "Click behavior" -->

- Status: Proposed <!-- Proposed | Accepted | Rejected | Superseded by [NNNN](NNNN-title.md) -->
- Date: YYYY-MM-DD <!-- date the status last changed -->
- Discussion: <!-- link to this record's PR; add prior issues/threads under Context -->

## Context
Expand All @@ -14,40 +13,47 @@ expectations, existing behavior that differs between bindings, implementation co
Link prior discussions (issues, TLC notes) here as background — but summarize them, since
this section must make sense without following any links.

<!-- Optional: when bindings currently differ, a table makes the divergence concrete. This is
the as-is state as of this decision (durable rationale) — NOT convergence tracking, which
lives in the post-acceptance tracking issue. Delete it if the decision is greenfield or the
bindings already behave the same. -->

| Binding | Current behavior |
|------------|------------------|
| Java | |
| Python | |
| Ruby | |
| .NET | |
| JavaScript | |

## Decision

The decision, stated in language-neutral terms. This is the normative part: what every
binding MUST do, and what is explicitly left to per-language idiom. Use code sketches per
language here if the API shape is part of what's being decided.
binding MUST do, and what is explicitly left to per-language idiom. Record *what* and *why*,
not *how* — implementation lives in the adopting PRs. Use code sketches only to pin down the
API shape being decided, not to specify implementation.

## Considered options

- **Option A** — what it is; why it was rejected or accepted
- **Option B** — what it is; why it was rejected or accepted

<!-- Options must be mutually exclusive answers to the question stated in Context; if two
options could both be adopted, they are separate decisions and the document should be
split. Revise this section during review as alternatives are contested or added — the
merged record, not the PR thread, is the authoritative account of why each rejected
option was not chosen. -->
<!-- List the alternatives to the decision above and why each was rejected. These are mutually
exclusive answers to the same question, not a menu of separable features — a record may
bundle related sub-choices (give each its own options); independent adoptability alone is
not grounds to split it (see the README's scoping guidance). Revise this section during
review as alternatives are contested or added — the merged record, not the PR thread, is
the authoritative account of why each rejected option was not chosen. -->

## Consequences

What gets easier, what gets harder, what users will notice. Deprecations triggered by this
decision and their timelines. Follow-up decisions this one makes necessary.

## Binding status

<!-- Update this table as bindings converge on the decision; table updates don't need
TLC review. "n/a" with a note if the decision doesn't apply to a binding. -->

| Binding | Status | Notes / tracking link |
|------------|---------|-----------------------|
| Java | pending | |
| Python | pending | |
| Ruby | pending | |
| .NET | pending | |
| JavaScript | pending | |
<!-- Per-binding convergence is NOT tracked here. When this record is accepted, open an ADR
tracking issue (the "ADR Implementation Tracking" issue template) with one checkbox per
binding, and link it from this record's PR. Keeping it out of the committed record avoids
churn on an otherwise immutable file. -->

## Appendix (optional)

Expand Down
44 changes: 33 additions & 11 deletions docs/decisions/README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Design Decisions

This directory is the log of design decisions that apply across the Selenium project —
one file per decision, numbered in the order they were proposed.
one file per decision, numbered by the pull request that proposes it.

Selenium ships the same API in multiple languages. Decisions about user-visible behavior,
API shape, and cross-binding semantics need to be made once, recorded, and implemented
Expand All @@ -25,11 +25,29 @@ question comes up in review, the answer should be a link to a file here.

When in doubt, ask whether the question is likely to be raised again. If it is, record the decision.

## Scope: what belongs in one record

A record captures one coherent decision — which usually means a cluster of related sub-choices
that share the same context and rationale and are settled as a unit. Bundling those is correct,
not a flaw: a record on how clicks behave can settle scrolling, hit-testing, and pointer movement
together because they are one design with one rationale.

The test for splitting is **not** "could this part be adopted on its own?" — almost any part can.
Split only when a sub-choice has its own rationale that stands without the others, would be debated
and decided separately, or could later be reversed without disturbing the rest. If splitting would
force a reader to open several records to understand any one of them, they belong in the same record.

## Process

1. **Propose.** Anyone may propose: copy [0000-template.md](0000-template.md) to `NNNN-short-title.md` using the
next unused number, fill it in, and open a PR with `Status: Proposed`. Keep it to about a
page — if the debate already happened in an issue, the record can be short and link to it.
1. **Propose.** Anyone may propose: copy [0000-template.md](0000-template.md) to `short-title.md`,
fill it in with `Status: Proposed`, and open a PR. Once GitHub assigns the PR number, rename the
file to `NNNN-short-title.md` using that number, before merge. Keep it to about a page — if the
debate already happened in an issue, the record can be short and link to it.

Open the PR with the ADR pull-request template by appending `?expand=1&template=adr.md` to the
compare URL — GitHub has no picker for PR templates, so this query parameter is the only way to
select it (e.g. `https://github.com/SeleniumHQ/selenium/compare/trunk...your-branch?expand=1&template=adr.md`).
Keep the PR body to review logistics; the decision and rationale belong in the record, not the PR.
2. **Discuss.** The PR thread is the discussion record. Decisions that need synchronous
discussion are raised at a TLC meeting; the outcome goes back into the PR. Disagreement
about the considered options is resolved by revising the document during review, so the
Expand All @@ -40,8 +58,11 @@ When in doubt, ask whether the question is likely to be raised again. If it is,
merging constitutes acceptance. Proposals the TLC considers and declines are merged as
`Rejected`; proposals withdrawn or abandoned before TLC consideration are closed and the
number lapses.
4. **Implement.** Each binding tracks its convergence in the decision's binding-status table.
Updating that table (and only that table) doesn't require TLC review.
4. **Implement.** When a record is accepted, open an ADR tracking issue (use the
[ADR Implementation Tracking](https://github.com/SeleniumHQ/selenium/issues/new?template=adr-tracking.yml) issue template) — one
checkbox per binding, linking each implementing PR as it lands — and link the issue from the
record's PR. Tracking lives in the issue, not the committed record, so the immutable file doesn't
churn as bindings converge; updating the issue needs no TLC review.

## Approval

Expand All @@ -62,10 +83,11 @@ When in doubt, ask whether the question is likely to be raised again. If it is,

- **A decision must stand alone.** A reader gets the decision, the rationale, and the rejected
alternatives without following any links; linked material is background, not required reading.
- **Accepted decisions are immutable**, except for the status line and the binding-status
table. Changing a decision means a new record that supersedes the old one — update the old
record's status to `Superseded by [NNNN](...)`.
- **Numbers are stable once merged.** They get cited in reviews and issues. If two open PRs
claim the same number, the later one renames before merge. Gaps in numbering are acceptable.
- **A record fixes the decision and its rationale, not the implementation.** It says what every
binding must do and why; how each binding builds it lives in the adopting PRs and code.
- **Accepted decisions are immutable**, except for the status line. Changing a decision means a
new record that supersedes the old one — update the old record's status to `Superseded by [NNNN](...)`.
- **The number is the proposal's PR number.** It gets cited in reviews and issues and links
straight to the discussion. Gaps in numbering are expected.
- **Durable supporting material goes in the record itself** (an Appendix section at the end).
Ephemeral evidence and debate stay in the PR thread.