Skip to content

Commit aaeff8f

Browse files
authored
Merge pull request #93 from Integration-Automation/dev
Split extended_features into 10 thematic subdocs
2 parents b19ac22 + 916ce49 commit aaeff8f

24 files changed

Lines changed: 1180 additions & 1125 deletions

File tree

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
============
2+
Architecture
3+
============
4+
5+
System overview
6+
===============
7+
8+
.. mermaid::
9+
10+
flowchart LR
11+
A1["Action JSON"] --> EXE["Executor"]
12+
A2["Recorder"] --> A1
13+
A3["LLM NL → draft"] --> A1
14+
EXE --> SEL["Selenium"]
15+
EXE --> PW["Playwright"]
16+
EXE --> APM["Appium"]
17+
EXE --> HTTP["HTTP API"]
18+
EXE --> DB["Database"]
19+
SEL --> REC["Records"]
20+
PW --> REC
21+
REC --> REP["Reports"]
22+
REC --> OBS["Observability"]
23+
REC --> NOT["Notifiers"]
24+
25+
Action lifecycle
26+
================
27+
28+
.. mermaid::
29+
30+
flowchart LR
31+
IN["[cmd, args, kwargs]"] --> VAL["Validator"]
32+
VAL --> ENV["${ENV.X} / ${ROW.x}"]
33+
ENV --> SPAN["OTel span"]
34+
SPAN --> RETRY["Retry policy"]
35+
RETRY --> GATE["Script gate"]
36+
GATE --> DISP["event_dict[cmd]"]
37+
DISP --> RECORD["records.append"]
38+
DISP -- failure --> SHOT["Auto screenshot"]
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
========
2+
Backends
3+
========
4+
5+
Selenium (default)
6+
==================
7+
8+
The original ``WebDriverWrapper`` plus ``WebElementWrapper``. All commands
9+
without a more specific prefix dispatch here.
10+
11+
Playwright
12+
==========
13+
14+
A full mirror of the Selenium surface lives under ``WR_pw_*``:
15+
16+
* Lifecycle / pages / navigation
17+
* Find (with ``TestObject`` translation) and direct page-level shortcuts
18+
* Element-level wrapper
19+
* Mobile emulation, locale, timezone, geolocation, permissions, clock
20+
* HAR recording, route mocking, console + network event capture
21+
* Network throttling presets via CDP
22+
23+
Switch is opt-in: existing scripts keep running on Selenium.
24+
25+
Cloud Grid
26+
==========
27+
28+
Provider helpers for BrowserStack, Sauce Labs, and LambdaTest:
29+
30+
* ``connect_browserstack`` / ``connect_saucelabs`` / ``connect_lambdatest``
31+
* ``build_browserstack_capabilities`` / ``build_saucelabs_capabilities`` /
32+
``build_lambdatest_capabilities``
33+
* ``start_remote_driver`` for arbitrary hub URLs
34+
35+
Appium (mobile)
36+
===============
37+
38+
``start_appium_session`` builds an Appium WebDriver and registers it on the
39+
shared Selenium wrapper so existing ``WR_*`` commands keep working against a
40+
mobile session. Capability builders cover both Android (UiAutomator2) and
41+
iOS (XCUITest).
42+
43+
``appium_integration.gestures`` adds higher-level mobile gestures —
44+
``swipe`` / ``scroll`` / ``long_press`` / ``pinch`` / ``double_tap``
45+
prefer Appium's ``mobile:`` named extensions and fall back to W3C Actions
46+
sequences.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
=================
2+
Browser internals
3+
=================
4+
5+
* **CDP** — ``selenium_cdp`` / ``playwright_cdp`` raw passthroughs.
6+
* **Storage** — ``localStorage`` / ``sessionStorage`` / ``IndexedDB`` get /
7+
set / clear via injected JS.
8+
* **Service worker / cache** — unregister / clear caches /
9+
``Network.setBypassServiceWorker``.
10+
* **Console + network capture** — Playwright event listeners with
11+
assertions (``no console errors`` / ``no 5xx``).
12+
* **Shadow DOM** — selector chains pierce nested shadow roots.
13+
* **iframes** — switch chains and Playwright frame-locator chains.
14+
* **File upload / download** — element ``send_keys`` / ``set_input_files``
15+
for upload; ``wait_for_download`` polls a directory for completed files.
16+
* **Browser extension loaders** — Chrome ``add_extension`` / Playwright
17+
``--load-extension``.
18+
19+
Browser & locale
20+
================
21+
22+
* ``device_emulation`` — ``available_presets`` /
23+
``playwright_kwargs("iPhone 15 Pro")`` /
24+
``apply_to_chrome_options(opts, "Desktop 1080p")`` /
25+
``cdp_emulation_command(name)``.
26+
* ``geo_locale.GeoOverride`` — yields both
27+
``cdp_payloads(override)`` and ``playwright_context_kwargs(override)``.
28+
* ``multi_tab.TabChoreographer`` — track tabs by alias;
29+
``register_current`` / ``open_new`` / ``switch_to`` / ``with_tab`` /
30+
``close``.
31+
* ``webauthn.enable_virtual_authenticator(driver)`` — CDP
32+
``WebAuthn.addVirtualAuthenticator`` for passkey simulation.
33+
34+
Storybook / shadow DOM
35+
======================
36+
37+
* ``storybook.discover_stories(index_or_path)`` reads Storybook 7+
38+
``index.json``;
39+
``plan_actions_for_stories(stories, base_url, run_a11y=True,
40+
capture_screenshot=True, extra_per_story=...)`` builds a flat action
41+
plan that visits each story under ``iframe.html?id=...`` and runs
42+
axe / screenshot.
43+
* ``storybook.visual_snapshots.capture_story_snapshots(stories,
44+
base_url, take_screenshot, navigate, baseline_dir=...)`` — per-story
45+
PNG capture with byte-level baseline comparison.
46+
* ``dom_traversal.shadow_pierce.find_first(driver, css_selector)`` /
47+
``find_all`` walk open shadow roots recursively. ``execute_script``
48+
for Selenium, ``evaluate`` for Playwright; ``assert_pierced_visible``
49+
raises if the selector doesn't match anywhere.
50+
51+
CDP tap / cross-browser / state diff
52+
====================================
53+
54+
* ``cdp_tap.CdpRecorder(output_path).attach(driver)`` — wraps
55+
``execute_cdp_cmd`` so every call is appended to an ndjson log;
56+
``CdpReplayer(load_recording(path))`` plays the same sequence back.
57+
* ``cross_browser.diff_runs([chromium_run, firefox_run, webkit_run])``
58+
— buckets findings into ``major`` / ``minor`` (5xx → major,
59+
screenshot hash → minor); ``assert_parity(report, only_major=True)``
60+
is the CI gate.
61+
* ``state_diff.capture_state(driver)`` snapshots cookies +
62+
localStorage + sessionStorage; ``diff_states(before, after)`` reports
63+
added / removed / changed keys per section.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
==============================
2+
Cookbook, tiers & API façade
3+
==============================
4+
5+
Cookbook examples
6+
=================
7+
8+
The ``examples/`` directory ships runnable recipes that drive real Chrome
9+
end-to-end. Each found a real bug the unit suite missed:
10+
11+
* ``counting_stars.{py,json}`` — open YouTube and play OneRepublic
12+
Counting Stars; revealed the bug where
13+
``webdriver_wrapper.execute_script`` was swallowing return values.
14+
* ``google_search.py`` — consent dismissal + result heading scrape.
15+
* ``form_submit.py`` — ``form_autofill.plan_fill_actions`` +
16+
``state_diff.capture_state`` round trip against ``httpbin``.
17+
* ``smart_wait_demo.py`` — ``wait_for_fetch_idle``,
18+
``wait_for_spa_route_stable``, ``memory_leak.detect_growth``.
19+
* ``fanout_demo.py`` — parallel HTTP preflights via ``run_fan_out``.
20+
* ``pii_redact_demo.py`` — pure-logic ``scan_text`` / ``redact_text``.
21+
22+
Test tiers
23+
==========
24+
25+
* ``test/unit_test/`` — 1200 mock-based unit tests, ~12s.
26+
* ``test/integration_test/`` — 30 wired-modules tests with real I/O
27+
(in-memory SQLite, in-process HTTP servers, real subprocesses for
28+
the MCP / LSP). Surfaced the Windows LSP CRLF framing bug.
29+
* ``test/e2e_test/`` — six real-browser smoke tests; skips cleanly when
30+
``WEBRUNNER_E2E_HUB`` doesn't resolve. Use
31+
``cd docker && docker compose up -d`` locally;
32+
``.github/workflows/e2e_browser.yml`` runs them daily / on demand.
33+
34+
Thematic façade
35+
===============
36+
37+
The 80+ helpers under ``je_web_runner.utils.<area>`` are also re-exported
38+
under ``je_web_runner.api`` grouped by theme:
39+
40+
.. code-block:: python
41+
42+
from je_web_runner.api import (
43+
authoring, debugging, frontend, infra, mobile,
44+
networking, observability, quality, reliability,
45+
security, test_data,
46+
)
47+
48+
The original Selenium-flavoured top-level surface stays unchanged so
49+
existing user code keeps working.
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
=========
2+
Test data
3+
=========
4+
5+
* **Faker integration** — ``fake_email`` / ``fake_name`` / ``fake_value`` and
6+
friends; ``faker`` is a soft dependency.
7+
* **Factories** — ``Factory(defaults)`` evaluates callable defaults per
8+
``build()``; pre-built ``user_factory`` / ``order_factory`` /
9+
``product_factory``.
10+
* **Testcontainers** — ``start_postgres`` / ``start_redis`` /
11+
``start_generic`` wrap testcontainers-python.
12+
* **.env loader + ${ENV.X}** — ``load_env`` / ``expand_in_action`` so the
13+
same actions can target dev / staging / prod.
14+
* **Data-driven runner** — ``load_dataset_csv`` / ``load_dataset_json`` /
15+
``run_with_dataset`` with ``${ROW.col}`` placeholder expansion.
16+
17+
Test data & determinism
18+
=======================
19+
20+
* ``snapshot.fixture_record.FixtureRecorder("fx.json", mode="auto")`` —
21+
record once, replay forever; modes ``record`` / ``replay`` / ``auto``.
22+
* ``database.fixtures.load_fixture_file("seed.json")`` +
23+
``load_into_connection(conn, fixture)`` — seed Postgres / MySQL /
24+
SQLite from ``{table: [rows]}`` JSON.
25+
26+
Auth, API, database
27+
===================
28+
29+
* **OAuth2 / OIDC** — ``client_credentials_token`` / ``password_grant_token``
30+
/ ``refresh_token_grant`` with in-process token cache that refreshes 30 s
31+
before expiry.
32+
* **HTTP API** — ``http_get`` / ``http_post`` / ``http_put`` / ``http_patch``
33+
/ ``http_delete`` plus ``http_assert_status`` and
34+
``http_assert_json_contains``.
35+
* **Database** — ``db_query`` / ``db_assert_count`` / ``db_assert_value`` /
36+
``db_assert_exists`` / ``db_assert_empty``; SQLAlchemy soft dependency,
37+
bound parameters only.
38+
39+
API & contract testing
40+
======================
41+
42+
* ``api_mock.MockRouter().add(method, url_pattern, body=, status=, times=)``
43+
— supports literal, glob, and ``re:`` regex URL patterns; attach to a
44+
Playwright page with ``attach_to_page(page)``.
45+
* ``contract_testing.validate_response(body, schema)`` — JSON-Schema
46+
subset (type / properties / required / items / enum / oneOf /
47+
additionalProperties); ``validate_against_openapi`` resolves
48+
``$ref`` and looks up ``paths[…].responses[…]``.
49+
* ``graphql.GraphQLClient(endpoint).execute(query, variables=)`` +
50+
``extract_field(payload, "users[0].name")``.
51+
* ``mock_services`` — ``MockOAuthServer``, ``MockSmtpServer``,
52+
``MockS3Storage`` for offline CI runs.

0 commit comments

Comments
 (0)