You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs: address residual NITs from ADR 0004 round 2 review
Round 2 review APPROVED with 3 residual NITs and 3 optional improvements.
Address all six in one tight cleanup:
NITs:
- Align findings.md to use "statements" not "lines" for the ~14 figure
(matches body of ADR after round 1 wording change)
- Add (per single-element measurement; see body) caveat to TL;DR's 14x
verbosity claim
- Sketch the 3-5x calibration: lower bound assumes harder keywords are
Python-control-flow-dominated and roughly equal cost in either lib;
upper bound assumes Playwright still wins on selector strategy and
auto-wait
Optional:
- Phase M2 commits to a follow-up ADR for realized numbers, addressing
the round 1 immutability concern more durably
- Track A page object row clarifies "(34 cases across 4 page-object
suites)"
- Pull no-E2E-test-passed into its own Risk bullet (was nested inside
sample-size-bias risk) for parity with top-of-evidence callout
- Tighten findings.md cost-ratio paragraph to honour the single-sample
caveat (was "anything depth-bound pays this 14x verbosity tax";
now scoped to the measured element with explicit
did-not-measure-distribution disclosure)
For the Account list view alone, with 452 shadow roots, anything that depends on a shadow-DOM-bound element pays this 14× verbosity tax under Selenium 4.
41
+
For this single measured element, the Selenium 4 path is ~14× more verbose than the Playwright path. The 452 shadow-host count above describes how heavily Lightning is LWC-componentized on this page; it is a count of shadow hosts, not of unreachable elements. Other shadow-DOM-bound elements in the test suite may be 1–2 hops shallow or 6+ hops deep — we did not measure the distribution.
Copy file name to clipboardExpand all lines: docs/adrs/0004-robot-framework-selenium-vs-playwright.md
+6-4Lines changed: 6 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ author: "@jstvz"
8
8
9
9
## TL;DR
10
10
11
-
Migrate CumulusCI's Robot Framework browser-test infrastructure from Selenium 3 to `robotframework-browser` (Playwright) over a time-bounded deprecation period (Phases M1–M5, expected 6–12 months for the downstream-coordination tail). Selenium 4 is no longer required. The `sf:` locator prefix and `Salesforce.robot` resource remain available during deprecation; downstream consumers (NPSP, EDA, OFM, V4S) migrate on their own schedule with tooling support. Selenium per-release maintenance is tractable today (4 locator overrides bridged 10 API versions) but its shadow-DOM trajectory is structurally bad and Selenium 4 only shifts the brittleness from Aura to LWC at ~14× the verbosity.
11
+
Migrate CumulusCI's Robot Framework browser-test infrastructure from Selenium 3 to `robotframework-browser` (Playwright) over a time-bounded deprecation period (Phases M1–M5, expected 6–12 months for the downstream-coordination tail). Selenium 4 is no longer required. The `sf:` locator prefix and `Salesforce.robot` resource remain available during deprecation; downstream consumers (NPSP, EDA, OFM, V4S) migrate on their own schedule with tooling support. Selenium per-release maintenance is tractable today (4 locator overrides bridged 10 API versions) but its shadow-DOM trajectory is structurally bad and Selenium 4 only shifts the brittleness from Aura to LWC at ~14× the verbosity (per single-element measurement; see body).
12
12
13
13
## Context and Problem Statement
14
14
@@ -49,7 +49,7 @@ We need to decide CumulusCI's Robot Framework path: continue Selenium with agent
| Page object failures |**5** — inline locators in [`ObjectManagerPageObject.py`](../../cumulusci/robotframework/pageobjects/ObjectManagerPageObject.py) (Save button changed `<input>`→`<button>`, sidebar link text changed). These are inline locators outside the versioning system. |
| Surface area | 41 versioned locators, ~37 keywords in `Salesforce.py`, page objects, form_handlers dispatch — full system to maintain. |
@@ -98,7 +98,7 @@ All numbers below are from direct observation; they give an accurate sense of sc
98
98
1.**The two rates are not directly comparable.** Track A's lines are mostly XPath fragments and test fixtures debugged against a live org. Track B's lines are mostly keyword bodies and docstrings written from scratch. Lines-per-minute is a rough engineering proxy, not a precise metric.
99
99
2.**Sample-size bias.** The 10 ported keywords are the easier surface (modals, app launcher, simple form fill). The harder surface — page object model, [`form_handlers.py`](../../cumulusci/robotframework/form_handlers.py) dispatch table, label-locator strategy, related-list popups — was not ported. Those keywords contain non-trivial Python logic that doesn't get cheaper just because the underlying browser library changed.
100
100
101
-
A defensible engineering estimate for the **full port** is **3–5× faster than equivalent Selenium maintenance**, not 20×. This is not a measured number; it is a calibrated estimate based on the complexity of the unported surface. Phase M2 will produce real per-keyword data that should refine this estimate (and we will publish a follow-up ADR with realized numbers — see Consequences).
101
+
A defensible engineering estimate for the **full port** is **3–5× faster than equivalent Selenium maintenance**, not 20×. This is not a measured number; it is a calibrated estimate based on the complexity of the unported surface. The lower bound (3×) assumes the harder keywords are dominated by Python control flow (page object model, `form_handlers` dispatch, label strategy) that costs roughly the same in either library; the upper bound (5×) assumes Playwright still wins on selector strategy and auto-wait even where the Python logic is comparable. Phase M2 will produce real per-keyword data that should refine this estimate (and we will publish a follow-up ADR with realized numbers — see Consequences).
102
102
103
103
### Per-release maintenance trajectory
104
104
@@ -200,6 +200,7 @@ Phased plan with realistic durations.
200
200
- Port the remaining ~27 keywords from `Salesforce.py` (the harder surface: page object model, `form_handlers` dispatch, label strategy, related-list popups, performance keywords)
201
201
- Each PR ports a coherent group, includes a Playwright-side test, and is reviewed independently
202
202
- Track per-keyword effort to refine the 3–5× estimate
203
+
- Outcomes (realized full-port cost, any unforeseen complexity) will be published as a follow-up ADR rather than amending this one — ADRs are durable records by design
203
204
204
205
**Phase M3 — Compatibility surface for downstream (~2–4 weeks for shim; runtime translator deferred unless data warrants)**
205
206
@@ -235,7 +236,8 @@ Phased plan with realistic durations.
-**Negative:** Breaking change for downstream consumers, even with a deprecation window. Coordination effort with NPSP, EDA, OFM, V4S maintainers measured in months, not weeks.
237
238
-**Negative:** Adds Node.js + Playwright binary dependency for users who run browser tests.
238
-
-**Risk:** Sample-size bias — the 10-keyword PoC tested the easy surface and no Playwright E2E test passed end-to-end. The harder keywords (page object model, form_handlers) and the runtime infrastructure may surface unforeseen complexity. **Mitigation:** Phase M1 establishes runtime validity before Phase M2 commits to the full port; Phase M2 is structured as ~5 independent PRs, each with its own validation, so the cost gets revealed incrementally rather than as a big-bang surprise.
239
+
-**Risk:** No Playwright end-to-end test passed during the PoC. The 10 ported keywords were validated by static review and selector-strategy analysis only; runtime correctness rests on Phase M1's regex bug fix unlocking E2E execution. **Mitigation:** Phase M1 is small, well-scoped, and runs first; if it surfaces deeper infrastructure problems, the migration plan can be revisited before committing to Phase M2.
240
+
-**Risk:** Sample-size bias — the 10-keyword PoC tested the easy surface. The harder keywords (page object model, form_handlers, label strategy, related-list popups) may surface unforeseen complexity in runtime behaviour, not just selector strategy. **Mitigation:** Phase M2 is structured as ~5 independent PRs, each with its own validation, so the cost gets revealed incrementally rather than as a big-bang surprise.
239
241
-**Risk:** The 3–5× full-port efficiency estimate is calibrated, not measured. **Mitigation:** Phase M2 produces real per-keyword data; we will publish a follow-up ADR (or a supersedes-style update) with the realized numbers once the port is complete.
240
242
-**Risk:** Downstream maintainers may not have capacity to migrate within the deprecation window. **Mitigation:** long deprecation window (≥1 major version + the realized M4 tail), `SalesforceCompat.robot` shim, automated migration tooling, willingness to extend the EOL version if needed.
241
243
-**Risk:** Selenium 4 measurement was a single sample on a single element. **Mitigation:** the qualitative architectural claim (LWC host-chain names are implementation details and as brittle as Aura) generalizes from the host-chain composition, not from the specific 14-statement cost; the decision does not hinge on the precise number.
0 commit comments