browsercontrol 0.1.2__tar.gz → 0.1.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- browsercontrol-0.1.4/.claude/settings.local.json +10 -0
- browsercontrol-0.1.4/.github/workflows/ci.yml +135 -0
- browsercontrol-0.1.4/.github/workflows/dependency-review.yml +39 -0
- {browsercontrol-0.1.2 → browsercontrol-0.1.4}/.gitignore +3 -6
- browsercontrol-0.1.4/.pre-commit-config.yaml +48 -0
- browsercontrol-0.1.4/CLAUDE.md +114 -0
- browsercontrol-0.1.4/CODE_QUALITY.md +81 -0
- {browsercontrol-0.1.2 → browsercontrol-0.1.4}/CONTRIBUTING.md +25 -2
- {browsercontrol-0.1.2 → browsercontrol-0.1.4}/PKG-INFO +291 -102
- {browsercontrol-0.1.2 → browsercontrol-0.1.4}/README.md +290 -101
- browsercontrol-0.1.4/assets/logo-main.png +0 -0
- {browsercontrol-0.1.2 → browsercontrol-0.1.4}/browsercontrol/__init__.py +1 -1
- {browsercontrol-0.1.2 → browsercontrol-0.1.4}/browsercontrol/__main__.py +1 -1
- {browsercontrol-0.1.2 → browsercontrol-0.1.4}/browsercontrol/browser.py +273 -227
- {browsercontrol-0.1.2 → browsercontrol-0.1.4}/browsercontrol/config.py +18 -22
- {browsercontrol-0.1.2 → browsercontrol-0.1.4}/browsercontrol/server.py +5 -12
- {browsercontrol-0.1.2 → browsercontrol-0.1.4}/browsercontrol/tools/content.py +36 -38
- {browsercontrol-0.1.2 → browsercontrol-0.1.4}/browsercontrol/tools/devtools.py +124 -142
- {browsercontrol-0.1.2 → browsercontrol-0.1.4}/browsercontrol/tools/forms.py +51 -33
- {browsercontrol-0.1.2 → browsercontrol-0.1.4}/browsercontrol/tools/interaction.py +74 -45
- {browsercontrol-0.1.2 → browsercontrol-0.1.4}/browsercontrol/tools/navigation.py +37 -31
- browsercontrol-0.1.4/browsercontrol/tools/recording.py +166 -0
- {browsercontrol-0.1.2 → browsercontrol-0.1.4}/browsercontrol/tools/tabs.py +14 -14
- {browsercontrol-0.1.2 → browsercontrol-0.1.4}/pyproject.toml +50 -1
- browsercontrol-0.1.4/tests/__init__.py +0 -0
- browsercontrol-0.1.4/tests/conftest.py +127 -0
- browsercontrol-0.1.4/tests/test_browser.py +367 -0
- browsercontrol-0.1.4/tests/test_content.py +135 -0
- browsercontrol-0.1.4/tests/test_devtools.py +205 -0
- browsercontrol-0.1.4/tests/test_forms.py +151 -0
- browsercontrol-0.1.4/tests/test_interaction.py +235 -0
- browsercontrol-0.1.4/tests/test_navigation.py +167 -0
- browsercontrol-0.1.4/tests/test_recording.py +168 -0
- browsercontrol-0.1.4/tests/test_tabs.py +109 -0
- browsercontrol-0.1.4/uv.lock +2085 -0
- browsercontrol-0.1.2/assets/logo.png +0 -0
- browsercontrol-0.1.2/browsercontrol/tools/recording.py +0 -220
- browsercontrol-0.1.2/uv.lock +0 -1896
- {browsercontrol-0.1.2 → browsercontrol-0.1.4}/LICENSE +0 -0
- {browsercontrol-0.1.2 → browsercontrol-0.1.4}/browsercontrol/tools/__init__.py +3 -3
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: [main]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: [main]
|
|
8
|
+
|
|
9
|
+
jobs:
|
|
10
|
+
lint:
|
|
11
|
+
runs-on: ubuntu-latest
|
|
12
|
+
steps:
|
|
13
|
+
- name: Checkout
|
|
14
|
+
uses: actions/checkout@v4
|
|
15
|
+
with:
|
|
16
|
+
fetch-depth: 0
|
|
17
|
+
|
|
18
|
+
- name: Install uv
|
|
19
|
+
uses: astral-sh/setup-uv@v3
|
|
20
|
+
with:
|
|
21
|
+
version: "latest"
|
|
22
|
+
|
|
23
|
+
- name: Install dependencies
|
|
24
|
+
run: uv sync --all-extras
|
|
25
|
+
|
|
26
|
+
- name: Run pre-commit hooks
|
|
27
|
+
run: uv run pre-commit run --all-files
|
|
28
|
+
|
|
29
|
+
- name: Run ruff check
|
|
30
|
+
run: uv run ruff check .
|
|
31
|
+
|
|
32
|
+
- name: Run ruff format check
|
|
33
|
+
run: uv run ruff format --check .
|
|
34
|
+
|
|
35
|
+
test:
|
|
36
|
+
runs-on: ubuntu-latest
|
|
37
|
+
needs: lint
|
|
38
|
+
steps:
|
|
39
|
+
- name: Checkout
|
|
40
|
+
uses: actions/checkout@v4
|
|
41
|
+
|
|
42
|
+
- name: Install uv
|
|
43
|
+
uses: astral-sh/setup-uv@v3
|
|
44
|
+
with:
|
|
45
|
+
version: "latest"
|
|
46
|
+
|
|
47
|
+
- name: Install dependencies
|
|
48
|
+
run: uv sync --all-extras
|
|
49
|
+
|
|
50
|
+
- name: Install Playwright browsers
|
|
51
|
+
run: uv run playwright install chromium --with-deps
|
|
52
|
+
|
|
53
|
+
- name: Run tests
|
|
54
|
+
run: uv run pytest -v
|
|
55
|
+
|
|
56
|
+
# Test on Windows and macOS as well
|
|
57
|
+
test-windows:
|
|
58
|
+
runs-on: windows-latest
|
|
59
|
+
needs: lint
|
|
60
|
+
steps:
|
|
61
|
+
- name: Checkout
|
|
62
|
+
uses: actions/checkout@v4
|
|
63
|
+
|
|
64
|
+
- name: Install uv
|
|
65
|
+
uses: astral-sh/setup-uv@v3
|
|
66
|
+
with:
|
|
67
|
+
version: "latest"
|
|
68
|
+
|
|
69
|
+
- name: Install dependencies
|
|
70
|
+
run: uv sync --all-extras
|
|
71
|
+
|
|
72
|
+
- name: Install Playwright browsers
|
|
73
|
+
run: uv run playwright install chromium
|
|
74
|
+
|
|
75
|
+
- name: Run tests
|
|
76
|
+
run: uv run pytest -v
|
|
77
|
+
|
|
78
|
+
test-macos:
|
|
79
|
+
runs-on: macos-latest
|
|
80
|
+
needs: lint
|
|
81
|
+
steps:
|
|
82
|
+
- name: Checkout
|
|
83
|
+
uses: actions/checkout@v4
|
|
84
|
+
|
|
85
|
+
- name: Install uv
|
|
86
|
+
uses: astral-sh/setup-uv@v3
|
|
87
|
+
with:
|
|
88
|
+
version: "latest"
|
|
89
|
+
|
|
90
|
+
- name: Install dependencies
|
|
91
|
+
run: uv sync --all-extras
|
|
92
|
+
|
|
93
|
+
- name: Install Playwright browsers
|
|
94
|
+
run: uv run playwright install chromium
|
|
95
|
+
|
|
96
|
+
- name: Run tests
|
|
97
|
+
run: uv run pytest -v
|
|
98
|
+
|
|
99
|
+
security:
|
|
100
|
+
runs-on: ubuntu-latest
|
|
101
|
+
needs: lint
|
|
102
|
+
steps:
|
|
103
|
+
- name: Checkout
|
|
104
|
+
uses: actions/checkout@v4
|
|
105
|
+
with:
|
|
106
|
+
fetch-depth: 0
|
|
107
|
+
|
|
108
|
+
- name: Install uv
|
|
109
|
+
uses: astral-sh/setup-uv@v3
|
|
110
|
+
with:
|
|
111
|
+
version: "latest"
|
|
112
|
+
|
|
113
|
+
- name: Install dependencies
|
|
114
|
+
run: uv sync --all-extras
|
|
115
|
+
|
|
116
|
+
- name: Run bandit security checks
|
|
117
|
+
run: uv run bandit -c pyproject.toml -r . --exclude ./tests,./.venv
|
|
118
|
+
|
|
119
|
+
type-check:
|
|
120
|
+
runs-on: ubuntu-latest
|
|
121
|
+
needs: lint
|
|
122
|
+
steps:
|
|
123
|
+
- name: Checkout
|
|
124
|
+
uses: actions/checkout@v4
|
|
125
|
+
|
|
126
|
+
- name: Install uv
|
|
127
|
+
uses: astral-sh/setup-uv@v3
|
|
128
|
+
with:
|
|
129
|
+
version: "latest"
|
|
130
|
+
|
|
131
|
+
- name: Install dependencies
|
|
132
|
+
run: uv sync --all-extras
|
|
133
|
+
|
|
134
|
+
- name: Run mypy (if type hints are used)
|
|
135
|
+
run: uv run mypy browsercontrol/ || echo "No mypy configuration found"
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# Dependency Review Action
|
|
2
|
+
#
|
|
3
|
+
# This Action will scan dependency manifest files that change as part of a Pull Request,
|
|
4
|
+
# surfacing known-vulnerable versions of the packages declared or updated in the PR.
|
|
5
|
+
# Once installed, if the workflow run is marked as required, PRs introducing known-vulnerable
|
|
6
|
+
# packages will be blocked from merging.
|
|
7
|
+
#
|
|
8
|
+
# Source repository: https://github.com/actions/dependency-review-action
|
|
9
|
+
# Public documentation: https://docs.github.com/en/code-security/supply-chain-security/understanding-your-software-supply-chain/about-dependency-review#dependency-review-enforcement
|
|
10
|
+
name: "Dependency review"
|
|
11
|
+
on:
|
|
12
|
+
pull_request:
|
|
13
|
+
branches: ["main"]
|
|
14
|
+
|
|
15
|
+
# If using a dependency submission action in this workflow this permission will need to be set to:
|
|
16
|
+
#
|
|
17
|
+
# permissions:
|
|
18
|
+
# contents: write
|
|
19
|
+
#
|
|
20
|
+
# https://docs.github.com/en/enterprise-cloud@latest/code-security/supply-chain-security/understanding-your-software-supply-chain/using-the-dependency-submission-api
|
|
21
|
+
permissions:
|
|
22
|
+
contents: read
|
|
23
|
+
# Write permissions for pull-requests are required for using the `comment-summary-in-pr` option, comment out if you aren't using this option
|
|
24
|
+
pull-requests: write
|
|
25
|
+
|
|
26
|
+
jobs:
|
|
27
|
+
dependency-review:
|
|
28
|
+
runs-on: ubuntu-latest
|
|
29
|
+
steps:
|
|
30
|
+
- name: "Checkout repository"
|
|
31
|
+
uses: actions/checkout@v4
|
|
32
|
+
- name: "Dependency Review"
|
|
33
|
+
uses: actions/dependency-review-action@v4
|
|
34
|
+
# Commonly enabled options, see https://github.com/actions/dependency-review-action#configuration-options for all available options.
|
|
35
|
+
with:
|
|
36
|
+
comment-summary-in-pr: always
|
|
37
|
+
# fail-on-severity: moderate
|
|
38
|
+
# deny-licenses: GPL-1.0-or-later, LGPL-2.0-or-later
|
|
39
|
+
# retry-on-snapshot-warnings: true
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
repos:
|
|
2
|
+
# Ruff - Fast Python linter and formatter
|
|
3
|
+
- repo: https://github.com/astral-sh/ruff-pre-commit
|
|
4
|
+
rev: v0.8.4
|
|
5
|
+
hooks:
|
|
6
|
+
# Run the linter
|
|
7
|
+
- id: ruff
|
|
8
|
+
args: [--fix]
|
|
9
|
+
# Run the formatter
|
|
10
|
+
- id: ruff-format
|
|
11
|
+
|
|
12
|
+
# General file checks
|
|
13
|
+
- repo: https://github.com/pre-commit/pre-commit-hooks
|
|
14
|
+
rev: v5.0.0
|
|
15
|
+
hooks:
|
|
16
|
+
- id: trailing-whitespace
|
|
17
|
+
- id: end-of-file-fixer
|
|
18
|
+
- id: check-yaml
|
|
19
|
+
- id: check-toml
|
|
20
|
+
- id: check-json
|
|
21
|
+
- id: check-added-large-files
|
|
22
|
+
args: [--maxkb=1000]
|
|
23
|
+
- id: check-merge-conflict
|
|
24
|
+
- id: check-case-conflict
|
|
25
|
+
- id: mixed-line-ending
|
|
26
|
+
args: [--fix=lf]
|
|
27
|
+
|
|
28
|
+
# Python security checks
|
|
29
|
+
- repo: https://github.com/PyCQA/bandit
|
|
30
|
+
rev: 1.8.0
|
|
31
|
+
hooks:
|
|
32
|
+
- id: bandit
|
|
33
|
+
args: [-c, pyproject.toml]
|
|
34
|
+
additional_dependencies: ["bandit[toml]"]
|
|
35
|
+
exclude: ^tests/
|
|
36
|
+
|
|
37
|
+
# CI configuration
|
|
38
|
+
ci:
|
|
39
|
+
autofix_commit_msg: |
|
|
40
|
+
[pre-commit.ci] auto fixes from pre-commit hooks
|
|
41
|
+
|
|
42
|
+
for more information, see https://pre-commit.ci
|
|
43
|
+
autofix_prs: true
|
|
44
|
+
autoupdate_branch: ""
|
|
45
|
+
autoupdate_commit_msg: "[pre-commit.ci] pre-commit autoupdate"
|
|
46
|
+
autoupdate_schedule: weekly
|
|
47
|
+
skip: []
|
|
48
|
+
submodules: false
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Overview
|
|
6
|
+
|
|
7
|
+
BrowserControl is an MCP (Model Context Protocol) server that gives AI agents
|
|
8
|
+
vision-first browser automation via Playwright. Its defining idea is **Set of
|
|
9
|
+
Marks (SoM)**: every action returns an annotated screenshot where interactive
|
|
10
|
+
elements are overlaid with numbered red boxes, so the agent acts by referring to
|
|
11
|
+
an element's number (`click(7)`) instead of CSS selectors or XPath.
|
|
12
|
+
|
|
13
|
+
## Commands
|
|
14
|
+
|
|
15
|
+
This project uses `uv` for all dependency and task management.
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
uv sync # Install deps (use --all-extras in CI to include dev group)
|
|
19
|
+
uv run playwright install chromium # One-time: install the browser engine
|
|
20
|
+
|
|
21
|
+
uv run pytest # Run all tests
|
|
22
|
+
uv run pytest tests/test_navigation.py # Run a single test file
|
|
23
|
+
uv run pytest tests/test_navigation.py::TestScroll::test_scroll_down_medium # Single test
|
|
24
|
+
uv run pytest --cov=browsercontrol # With coverage
|
|
25
|
+
|
|
26
|
+
uv run ruff check . # Lint
|
|
27
|
+
uv run ruff check . --fix # Lint + autofix
|
|
28
|
+
uv run ruff format . # Format (line length 100, double quotes)
|
|
29
|
+
uv run mypy browsercontrol/ # Type-check (strict mode)
|
|
30
|
+
uv run bandit -c pyproject.toml -r . --exclude ./tests,./.venv # Security scan
|
|
31
|
+
uv run pre-commit run --all-files # Run every hook (mirrors the CI lint job)
|
|
32
|
+
|
|
33
|
+
uv run fastmcp dev browsercontrol/server.py # Run the server in dev mode with inspector
|
|
34
|
+
browsercontrol # Run the installed server (also: python -m browsercontrol)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
CI (`.github/workflows/ci.yml`) gates on the lint job first, then runs tests on
|
|
38
|
+
Linux/Windows/macOS plus bandit and mypy. Run `ruff check`, `ruff format`, and
|
|
39
|
+
`pytest` locally before pushing.
|
|
40
|
+
|
|
41
|
+
## Architecture
|
|
42
|
+
|
|
43
|
+
The flow is: agent calls an MCP tool → tool drives the Playwright page → a fresh
|
|
44
|
+
annotated screenshot + element map is captured → both are returned to the agent.
|
|
45
|
+
|
|
46
|
+
**`browser.py` — the heart of the system.** Exposes a single module-global
|
|
47
|
+
`browser = BrowserManager()` instance and a module-global `element_map` dict.
|
|
48
|
+
Key behaviors to understand before touching anything:
|
|
49
|
+
|
|
50
|
+
- `screenshot_with_som()` is called at the end of nearly every tool. It takes a
|
|
51
|
+
screenshot, runs `get_interactive_elements()` (injected JS that collects
|
|
52
|
+
visible, on-screen interactive elements and their bounding boxes), draws the
|
|
53
|
+
numbered boxes, and **overwrites the global `element_map`** with 1-indexed IDs.
|
|
54
|
+
- **Element IDs are ephemeral.** They are only valid against the most recent
|
|
55
|
+
screenshot. Any navigation, click, scroll, or screenshot regenerates the map
|
|
56
|
+
and renumbers everything. Tools look up the target via `get_element_map()` and
|
|
57
|
+
return an error listing valid IDs when the ID is missing.
|
|
58
|
+
- The browser uses `launch_persistent_context` against a profile directory
|
|
59
|
+
(`~/.browsercontrol/user_data` by default), so cookies, localStorage, and login
|
|
60
|
+
state persist across server restarts. Launch args include localhost proxy
|
|
61
|
+
bypass to avoid `ERR_CONNECTION_REFUSED`.
|
|
62
|
+
- DevTools data (console logs, network requests, page errors) is captured by
|
|
63
|
+
event listeners attached in `_setup_page_listeners`, auto-wired to every new
|
|
64
|
+
page/popup, and stored in capped in-memory ring buffers on the manager.
|
|
65
|
+
|
|
66
|
+
**`server.py` — composition root.** Creates the `FastMCP` instance, attaches a
|
|
67
|
+
`lifespan` context manager that starts/stops the browser, and calls each
|
|
68
|
+
`register_*_tools(mcp)`. The server-level `instructions` string is the prompt the
|
|
69
|
+
agent sees describing available tools — keep it in sync when adding tools.
|
|
70
|
+
|
|
71
|
+
**`tools/` — one module per category** (navigation, interaction, forms, content,
|
|
72
|
+
devtools, recording, tabs). Each exports a single `register_<category>_tools(mcp)`
|
|
73
|
+
function that defines inner `async` functions decorated with `@mcp.tool()`.
|
|
74
|
+
Conventions every tool follows:
|
|
75
|
+
|
|
76
|
+
- Signature returns `tuple[str, Image]`: a human-readable status string plus the
|
|
77
|
+
annotated screenshot.
|
|
78
|
+
- Starts with `await browser.ensure_started()` (lazily boots the browser if the
|
|
79
|
+
lifespan hasn't, e.g. in some test paths).
|
|
80
|
+
- Ends by building the result via a local `_get_screenshot_with_summary()`
|
|
81
|
+
helper. **This helper is duplicated verbatim in several tool modules** — if you
|
|
82
|
+
change the summary format, update every copy.
|
|
83
|
+
|
|
84
|
+
**`config.py`** — a `Config` dataclass loaded once at import via
|
|
85
|
+
`Config.from_env()` into a global `config`. All settings come from `BROWSER_*`
|
|
86
|
+
and `LOG_LEVEL` env vars (see README for the full table). Because it is read at
|
|
87
|
+
import time, env changes require a server restart.
|
|
88
|
+
|
|
89
|
+
## Testing conventions
|
|
90
|
+
|
|
91
|
+
Tests **do not launch a real browser** — everything is mocked. The pattern:
|
|
92
|
+
|
|
93
|
+
- `tests/conftest.py` provides `mock_browser_manager` (a fully stubbed
|
|
94
|
+
`BrowserManager`), `mock_page`, `mock_context`, and `sample_element_map`.
|
|
95
|
+
- A test registers the tools onto a throwaway `FastMCP("test")`, then patches the
|
|
96
|
+
module-level `browser` symbol **in that specific tool module** (e.g.
|
|
97
|
+
`patch("browsercontrol.tools.navigation.browser", mock_browser_manager)`) —
|
|
98
|
+
because each tool module does `from browsercontrol.browser import browser`, it
|
|
99
|
+
holds its own reference that must be patched independently.
|
|
100
|
+
- The tool callable is reached through FastMCP internals:
|
|
101
|
+
`mcp_server._tool_manager._tools["navigate_to"].fn(...)`.
|
|
102
|
+
- `asyncio_mode = "auto"` is set, so `async def test_*` runs without an explicit
|
|
103
|
+
marker (though existing tests also add `@pytest.mark.asyncio`).
|
|
104
|
+
|
|
105
|
+
When adding a tool, add a test covering both the happy path and graceful error
|
|
106
|
+
handling, following the existing per-module test files.
|
|
107
|
+
|
|
108
|
+
## Conventions
|
|
109
|
+
|
|
110
|
+
- Python 3.11+. Type hints are required and checked by mypy in **strict** mode
|
|
111
|
+
(`disallow_untyped_defs`, etc.) — annotate fully.
|
|
112
|
+
- Commits follow Conventional Commits (`feat:`, `fix:`, `docs:`, `chore:`).
|
|
113
|
+
- Pre-commit hooks (ruff, prettier for md/yaml/json, bandit) run on commit;
|
|
114
|
+
`git commit --no-verify` bypasses them but CI will still enforce them.
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
# Code Formatting and Quality
|
|
2
|
+
|
|
3
|
+
This project uses automated code formatting and linting tools to maintain code quality.
|
|
4
|
+
|
|
5
|
+
## Tools
|
|
6
|
+
|
|
7
|
+
- **[Ruff](https://github.com/astral-sh/ruff)** - Fast Python linter and formatter
|
|
8
|
+
- **[Pre-commit](https://pre-commit.com/)** - Git hooks for automated checks
|
|
9
|
+
- **[Prettier](https://prettier.io/)** - Markdown/YAML/JSON formatting
|
|
10
|
+
- **[Bandit](https://bandit.readthedocs.io/)** - Security vulnerability scanner
|
|
11
|
+
|
|
12
|
+
## Setup
|
|
13
|
+
|
|
14
|
+
The tools are already configured. To install the pre-commit hooks:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
uv sync
|
|
18
|
+
uv run pre-commit install
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
### Manual Formatting
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
# Check for linting issues
|
|
27
|
+
uv run ruff check .
|
|
28
|
+
|
|
29
|
+
# Auto-fix linting issues
|
|
30
|
+
uv run ruff check . --fix
|
|
31
|
+
|
|
32
|
+
# Format code
|
|
33
|
+
uv run ruff format .
|
|
34
|
+
|
|
35
|
+
# Run all pre-commit hooks manually
|
|
36
|
+
uv run pre-commit run --all-files
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Automatic Formatting
|
|
40
|
+
|
|
41
|
+
Pre-commit hooks run automatically on `git commit`. They will:
|
|
42
|
+
|
|
43
|
+
1. Run ruff linter and formatter
|
|
44
|
+
2. Trim trailing whitespace
|
|
45
|
+
3. Fix end-of-file issues
|
|
46
|
+
4. Format markdown/YAML/JSON with prettier
|
|
47
|
+
5. Check for security issues with bandit
|
|
48
|
+
|
|
49
|
+
If any hook fails, the commit will be aborted and files will be auto-fixed. Review the changes and commit again.
|
|
50
|
+
|
|
51
|
+
## Configuration
|
|
52
|
+
|
|
53
|
+
### Ruff
|
|
54
|
+
|
|
55
|
+
Configuration in `pyproject.toml`:
|
|
56
|
+
|
|
57
|
+
- **Line length**: 100 characters
|
|
58
|
+
- **Target Python**: 3.11+
|
|
59
|
+
- **Enabled rules**: pycodestyle, pyflakes, isort, pep8-naming, pyupgrade, bugbear, comprehensions, simplify, type-checking, Ruff-specific
|
|
60
|
+
- **Ignored rules**: E501 (line too long), B008 (function call in defaults), N805 (first arg naming), SIM117 (nested with), B904 (exception chaining)
|
|
61
|
+
|
|
62
|
+
### Pre-commit
|
|
63
|
+
|
|
64
|
+
Configuration in `.pre-commit-config.yaml`:
|
|
65
|
+
|
|
66
|
+
- Ruff linter and formatter
|
|
67
|
+
- General file checks (trailing whitespace, EOF, YAML/TOML/JSON validation, large files, merge conflicts)
|
|
68
|
+
- Prettier for markdown formatting
|
|
69
|
+
- Bandit for security checks (excludes tests, allows subprocess for Playwright)
|
|
70
|
+
|
|
71
|
+
## Bypassing Hooks
|
|
72
|
+
|
|
73
|
+
If you need to bypass pre-commit hooks (not recommended):
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
git commit --no-verify
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## CI Integration
|
|
80
|
+
|
|
81
|
+
Pre-commit.ci is configured to run automatically on pull requests and can auto-fix issues.
|
|
@@ -23,7 +23,11 @@ We love your input! We want to make contributing to BrowserControl as easy and t
|
|
|
23
23
|
```bash
|
|
24
24
|
uv run playwright install chromium
|
|
25
25
|
```
|
|
26
|
-
5. **
|
|
26
|
+
5. **Install pre-commit hooks**:
|
|
27
|
+
```bash
|
|
28
|
+
uv run pre-commit install
|
|
29
|
+
```
|
|
30
|
+
6. **Run the server in dev mode**:
|
|
27
31
|
```bash
|
|
28
32
|
uv run fastmcp dev browsercontrol/server.py
|
|
29
33
|
```
|
|
@@ -33,11 +37,13 @@ We love your input! We want to make contributing to BrowserControl as easy and t
|
|
|
33
37
|
We use [uv](https://github.com/astral-sh/uv) for dependency management and packaging. It's fast and reliable.
|
|
34
38
|
|
|
35
39
|
### Project Structure
|
|
40
|
+
|
|
36
41
|
- `browsercontrol/server.py`: Main MCP server definition
|
|
37
42
|
- `browsercontrol/browser.py`: Core logic (Playwright + Set of Marks)
|
|
38
43
|
- `browsercontrol/tools/`: Tool implementations split by category
|
|
39
44
|
|
|
40
45
|
### Making Changes
|
|
46
|
+
|
|
41
47
|
1. Create a branch for your feature: `git checkout -b feature/amazing-feature`
|
|
42
48
|
2. Implement your changes
|
|
43
49
|
3. Run tests (see below)
|
|
@@ -48,17 +54,33 @@ We use [uv](https://github.com/astral-sh/uv) for dependency management and packa
|
|
|
48
54
|
|
|
49
55
|
## 🧪 Testing
|
|
50
56
|
|
|
51
|
-
We use `pytest
|
|
57
|
+
We use `pytest` for testing and `ruff` for code quality. Please ensure all checks pass before submitting a PR.
|
|
52
58
|
|
|
53
59
|
```bash
|
|
54
60
|
# Run all tests
|
|
55
61
|
uv run pytest
|
|
56
62
|
|
|
63
|
+
# Run tests with coverage
|
|
64
|
+
uv run pytest --cov=browsercontrol
|
|
65
|
+
|
|
66
|
+
# Check code formatting and linting
|
|
67
|
+
uv run ruff check .
|
|
68
|
+
uv run ruff format .
|
|
69
|
+
|
|
70
|
+
# Run all pre-commit hooks
|
|
71
|
+
uv run pre-commit run --all-files
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
See [CODE_QUALITY.md](CODE_QUALITY.md) for more details on code formatting and quality tools.
|
|
75
|
+
|
|
57
76
|
# Run specific test file
|
|
77
|
+
|
|
58
78
|
uv run pytest tests/test_navigation.py
|
|
79
|
+
|
|
59
80
|
```
|
|
60
81
|
|
|
61
82
|
If you add a new tool or feature, please add a corresponding test case covering:
|
|
83
|
+
|
|
62
84
|
- Happy path (it works)
|
|
63
85
|
- Error handling (it fails gracefully)
|
|
64
86
|
|
|
@@ -82,3 +104,4 @@ Bugs are tracked as GitHub issues. When filing an issue, please explain the prob
|
|
|
82
104
|
## 📄 License
|
|
83
105
|
|
|
84
106
|
By contributing, you agree that your contributions will be licensed under its MIT License.
|
|
107
|
+
```
|