refactor: rename browser submodule to _browser to avoid shadowing browser()

This commit is contained in:
Mathew Sir Guest the best 2026-07-08 22:31:46 -06:00
parent b20cf0d10b
commit 8ed9565c88
4 changed files with 14 additions and 25 deletions

@ -50,7 +50,7 @@ wabot/ (repo root, branch feature/modernization
│ │ # ReattachingRemote, attach
│ ├── fields.py # PageObject, TextField, SelectField, CheckField, NullField
│ ├── page.py # Page (element maps, click, forms, alerts, waits)
│ ├── browser.py # Browser facade
│ ├── _browser.py # Browser facade (underscored to avoid shadowing browser())
│ └── screenshot.py # save_full_page (firefox raw cmd / chromium stitch)
├── tests/
│ ├── unit/ # test_pacing.py, test_sessions.py, test_hosts.py,
@ -2442,10 +2442,10 @@ git commit -m "feat: full-page screenshots (firefox raw command, chromium PIL st
---
### Task 11: `browser.py` — the Browser facade
### Task 11: `_browser.py` — the Browser facade
**Files:**
- Create: `src/wabot/browser.py`
- Create: `src/wabot/_browser.py`
- Test: `tests/unit/test_browser.py`
Naming note: the spec says "`reset_good_status()` retained"; under the approved free-API-redesign decision it is renamed to the cleaner `reset()` (same semantics: clears the broken-state flag). This is the only intentional naming deviation from the spec.
@ -2461,7 +2461,7 @@ from unittest.mock import MagicMock
import pytest
from selenium.common.exceptions import WebDriverException
from wabot.browser import Browser
from wabot._browser import Browser
from wabot.pacing import HumanPacing, NoPacing
from wabot.page import Page
@ -2581,7 +2581,7 @@ class TestQuit:
driver.quit.assert_called_once_with()
def test_quit_stops_managed_service(self, monkeypatch):
import wabot.browser as browser_mod
import wabot._browser as browser_mod
stopped = []
monkeypatch.setattr(browser_mod, "stop_service", lambda pid: stopped.append(pid))
@ -2593,7 +2593,7 @@ class TestQuit:
store.remove.assert_called_once_with("s1")
def test_quit_removes_record_even_if_driver_quit_raises(self, monkeypatch):
import wabot.browser as browser_mod
import wabot._browser as browser_mod
monkeypatch.setattr(browser_mod, "stop_service", lambda pid: None)
driver, store = MagicMock(), MagicMock()
@ -2612,7 +2612,7 @@ Expected: FAIL — `ModuleNotFoundError: No module named 'wabot.browser'`
- [ ] **Step 3: Write the implementation**
`src/wabot/browser.py`:
`src/wabot/_browser.py`:
```python
"""Browser: the facade consumers drive.
@ -2751,7 +2751,7 @@ Expected: 19 passed
- [ ] **Step 5: Commit**
```bash
git add src/wabot/browser.py tests/unit/test_browser.py
git add src/wabot/_browser.py tests/unit/test_browser.py
git commit -m "feat: Browser facade with working refuse-after-exception guard"
```
@ -3029,7 +3029,7 @@ from datetime import datetime, timezone
from selenium import webdriver
from selenium.common.exceptions import WebDriverException
from .browser import Browser
from ._browser import Browser
from .fields import CheckField, NullField, PageObject, SelectField, TextField
from .hosts import (
ExternalServer,
@ -3878,7 +3878,7 @@ Tooling: uv (`uv sync`), pytest (`uv run pytest`; real-browser suite via
Selenium 4 (pinned <5: session reattach relies on stable 4.x internals).
```
In the Architecture section: `BrowserProxy``Browser` (`src/wabot/browser.py`), add `pacing.py` (HumanPacing/NoPacing policies), and replace the dill/pickle description with: sessions persist as JSON records `(executor_url, session_id)` in `platformdirs.user_data_dir("wabot")/sessions.json`; `hosts.py` spawns detached driver services (`ManagedService`) or connects to external ones (`ExternalServer`); `ReattachingRemote.start_session` adopts the saved session id. Delete the Gotchas bullets about `LOGGER.trace`, undeclared deps, and star exports (all fixed); keep the Gotcha that external hosts must outlive Python and add: geckodriver reports `ready:false` while its single session is active, so liveness checks ignore the `ready` flag.
In the Architecture section: `BrowserProxy``Browser` (`src/wabot/_browser.py`), add `pacing.py` (HumanPacing/NoPacing policies), and replace the dill/pickle description with: sessions persist as JSON records `(executor_url, session_id)` in `platformdirs.user_data_dir("wabot")/sessions.json`; `hosts.py` spawns detached driver services (`ManagedService`) or connects to external ones (`ExternalServer`); `ReattachingRemote.start_session` adopts the saved session id. Delete the Gotchas bullets about `LOGGER.trace`, undeclared deps, and star exports (all fixed); keep the Gotcha that external hosts must outlive Python and add: geckodriver reports `ready:false` while its single session is active, so liveness checks ignore the `ready` flag.
- [ ] **Step 3: Full verification**

@ -18,7 +18,7 @@ from datetime import datetime, timezone
from selenium import webdriver
from selenium.common.exceptions import WebDriverException
from .browser import Browser
from ._browser import Browser
from .fields import CheckField, NullField, PageObject, SelectField, TextField
from .hosts import (
ExternalServer,

@ -4,7 +4,7 @@ from unittest.mock import MagicMock
import pytest
from selenium.common.exceptions import WebDriverException
from wabot.browser import Browser
from wabot._browser import Browser
from wabot.pacing import HumanPacing, NoPacing
from wabot.page import Page
@ -124,15 +124,7 @@ class TestQuit:
driver.quit.assert_called_once_with()
def test_quit_stops_managed_service(self, monkeypatch):
import sys
# NOTE(Task 12 wiring fix): `import wabot.browser as browser_mod` would
# resolve to `wabot.browser` the FUNCTION (the public API added in
# Task 12 shadows the submodule attribute of the same name on the
# `wabot` package once `wabot/__init__.py` defines `def browser(...)`).
# sys.modules keeps the real submodule reachable regardless of what
# the package's own `browser` attribute is rebound to.
browser_mod = sys.modules["wabot.browser"]
import wabot._browser as browser_mod
stopped = []
monkeypatch.setattr(browser_mod, "stop_service", lambda pid: stopped.append(pid))
@ -144,10 +136,7 @@ class TestQuit:
store.remove.assert_called_once_with("s1")
def test_quit_removes_record_even_if_driver_quit_raises(self, monkeypatch):
import sys
# see NOTE in test_quit_stops_managed_service above
browser_mod = sys.modules["wabot.browser"]
import wabot._browser as browser_mod
monkeypatch.setattr(browser_mod, "stop_service", lambda pid: None)
driver, store = MagicMock(), MagicMock()