pomelo-pw 0.15.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.
Files changed (35) hide show
  1. pomelo_pw-0.15.4/.gitignore +33 -0
  2. pomelo_pw-0.15.4/PKG-INFO +231 -0
  3. pomelo_pw-0.15.4/README.md +219 -0
  4. pomelo_pw-0.15.4/pyproject.toml +69 -0
  5. pomelo_pw-0.15.4/src/pomelo_pw/__init__.py +5 -0
  6. pomelo_pw-0.15.4/src/pomelo_pw/__main__.py +12 -0
  7. pomelo_pw-0.15.4/src/pomelo_pw/browser.py +36 -0
  8. pomelo_pw-0.15.4/src/pomelo_pw/cli.py +214 -0
  9. pomelo_pw-0.15.4/src/pomelo_pw/config/__init__.py +15 -0
  10. pomelo_pw-0.15.4/src/pomelo_pw/config/settings.py +128 -0
  11. pomelo_pw-0.15.4/src/pomelo_pw/error_context.py +130 -0
  12. pomelo_pw-0.15.4/src/pomelo_pw/executor.py +527 -0
  13. pomelo_pw-0.15.4/src/pomelo_pw/explorer.py +305 -0
  14. pomelo_pw-0.15.4/src/pomelo_pw/recorder.py +340 -0
  15. pomelo_pw-0.15.4/src/pomelo_pw/steps/__init__.py +64 -0
  16. pomelo_pw-0.15.4/src/pomelo_pw/steps/base.py +100 -0
  17. pomelo_pw-0.15.4/src/pomelo_pw/steps/check.py +27 -0
  18. pomelo_pw-0.15.4/src/pomelo_pw/steps/click.py +78 -0
  19. pomelo_pw-0.15.4/src/pomelo_pw/steps/conditional.py +116 -0
  20. pomelo_pw-0.15.4/src/pomelo_pw/steps/evaluate.py +117 -0
  21. pomelo_pw-0.15.4/src/pomelo_pw/steps/fill.py +28 -0
  22. pomelo_pw-0.15.4/src/pomelo_pw/steps/hover.py +27 -0
  23. pomelo_pw-0.15.4/src/pomelo_pw/steps/load_state.py +81 -0
  24. pomelo_pw-0.15.4/src/pomelo_pw/steps/loop.py +70 -0
  25. pomelo_pw-0.15.4/src/pomelo_pw/steps/navigate.py +46 -0
  26. pomelo_pw-0.15.4/src/pomelo_pw/steps/press.py +25 -0
  27. pomelo_pw-0.15.4/src/pomelo_pw/steps/save_state.py +43 -0
  28. pomelo_pw-0.15.4/src/pomelo_pw/steps/screenshot.py +203 -0
  29. pomelo_pw-0.15.4/src/pomelo_pw/steps/scroll.py +40 -0
  30. pomelo_pw-0.15.4/src/pomelo_pw/steps/select.py +44 -0
  31. pomelo_pw-0.15.4/src/pomelo_pw/steps/set_viewport.py +30 -0
  32. pomelo_pw-0.15.4/src/pomelo_pw/steps/type.py +29 -0
  33. pomelo_pw-0.15.4/src/pomelo_pw/steps/uncheck.py +27 -0
  34. pomelo_pw-0.15.4/src/pomelo_pw/steps/wait.py +183 -0
  35. pomelo_pw-0.15.4/src/pomelo_pw/substitution.py +85 -0
@@ -0,0 +1,33 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ .venv
8
+ venv/
9
+ .pytest_cache/
10
+ .mypy_cache/
11
+ .ruff_cache/
12
+ coverage/
13
+ *.cover
14
+ .coverage
15
+
16
+ # IDE
17
+ .idea/
18
+ .vscode/
19
+ *.swp
20
+ *.swo
21
+ *~
22
+
23
+ # OS
24
+ .DS_Store
25
+ Thumbs.db
26
+
27
+ # Env
28
+ .env
29
+ .env.local
30
+ .env.*.local
31
+
32
+ output
33
+ build/
@@ -0,0 +1,231 @@
1
+ Metadata-Version: 2.5
2
+ Name: pomelo-pw
3
+ Version: 0.15.4
4
+ Summary: Flow-based UI automation tool powered by Playwright
5
+ Requires-Python: >=3.12
6
+ Requires-Dist: click>=8.0.0
7
+ Requires-Dist: playwright>=1.40.0
8
+ Requires-Dist: pyyaml>=6.0
9
+ Provides-Extra: visual
10
+ Requires-Dist: pillow>=10.0.0; extra == 'visual'
11
+ Description-Content-Type: text/markdown
12
+
13
+ # Pomelo PW
14
+
15
+ [![CI](https://github.com/leoninew/pomelo-pw/actions/workflows/ci.yml/badge.svg)](https://github.com/leoninew/pomelo-pw/actions/workflows/ci.yml)
16
+
17
+ [English](README.md) | [简体中文](README_CN.md)
18
+
19
+ Pomelo PW is a Playwright-powered CLI for browser automation. It runs declarative YAML flows, so browser checks can live alongside application code without requiring a custom test harness.
20
+
21
+ It is intended for repeatable UI checks, scripted workflows, visual comparisons, and agent-assisted browser tasks. Flows validate their parameters before execution and collect screenshots, page snapshots, console errors, and network failures when a step fails.
22
+
23
+ ## What It Provides
24
+
25
+ - YAML flows with `{{variable}}` substitution and CLI overrides
26
+ - Browser steps for navigation, forms, waits, screenshots, state reuse, conditions, and loops
27
+ - Interactive explorer and recorder for finding selectors and creating starting flows
28
+ - Step-level retries, data-driven runs, and screenshot baseline comparison
29
+ - Native plugin packaging for Claude Code, Codex, and Grok Build
30
+
31
+ ## Install
32
+
33
+ Pomelo PW requires Python 3.12+ and [uv](https://docs.astral.sh/uv/).
34
+
35
+ ```bash
36
+ # Install the published CLI, then install its browser
37
+ uv tool install pomelo-pw
38
+ pomelo-pw install
39
+
40
+ # Or invoke the published package once without installing the CLI
41
+ uvx pomelo-pw install
42
+
43
+ # Work from a source checkout
44
+ uv sync --all-groups --locked
45
+ uv run pomelo-pw install
46
+ ```
47
+
48
+ The `install` command downloads Playwright Chromium for package installations. When run from a source checkout or the standalone binary, Pomelo PW uses an installed system Chrome or Chromium when it can find one.
49
+
50
+ Install visual comparison support only when flows use screenshot baselines:
51
+
52
+ ```bash
53
+ uv pip install pillow
54
+ ```
55
+
56
+ ## Quick Start
57
+
58
+ Create `smoke.yaml`:
59
+
60
+ ```yaml
61
+ name: example-smoke
62
+ variables:
63
+ base_url: "https://example.com"
64
+
65
+ steps:
66
+ - type: navigate
67
+ url: "{{base_url}}"
68
+ - type: screenshot
69
+ file: "homepage.png"
70
+ - type: scroll
71
+ direction: down
72
+ distance: 500
73
+ - type: screenshot
74
+ file: "scrolled.png"
75
+ ```
76
+
77
+ Run and validate it:
78
+
79
+ ```bash
80
+ uvx pomelo-pw validate smoke.yaml
81
+ uvx pomelo-pw run smoke.yaml --headless
82
+ ```
83
+
84
+ Screenshots and failure artifacts are written to `./smoke/` by default. Use `-o <directory>` to choose another output directory.
85
+
86
+ ## Use Pomelo PW
87
+
88
+ ### Find Selectors and Create Flows
89
+
90
+ ```bash
91
+ # Inspect a page and copy a selector from the interactive overlay
92
+ pomelo-pw explore https://example.com
93
+
94
+ # Record clicks, fills, and Enter presses into a YAML flow
95
+ pomelo-pw record https://example.com recorded-flow.yaml
96
+ ```
97
+
98
+ Prefer selectors based on stable semantics, such as `role=button[name="Continue"]`, over presentation-oriented CSS classes.
99
+
100
+ ### Run Flows
101
+
102
+ ```bash
103
+ # Run visibly with step progress
104
+ pomelo-pw run flow.yaml -v
105
+
106
+ # Run headlessly and emit the result as JSON
107
+ pomelo-pw run flow.yaml --headless --json
108
+
109
+ # Override a flow variable for this run
110
+ pomelo-pw run flow.yaml --var base_url=https://staging.example.com
111
+
112
+ # Validate YAML and step parameters without launching a browser
113
+ pomelo-pw validate flow.yaml
114
+ ```
115
+
116
+ Variables use `{{name}}`; CLI values take precedence over step-level values, which take precedence over flow-level values. The `${name}` form is preserved for JavaScript and shell template literals.
117
+
118
+ ### Author Flows
119
+
120
+ The following flow shows the common pattern: navigate, interact, wait for a meaningful result, then capture evidence.
121
+
122
+ ```yaml
123
+ name: login-smoke
124
+ variables:
125
+ base_url: "https://app.example.com"
126
+ username: "user@example.com"
127
+ password: "secret"
128
+
129
+ steps:
130
+ - type: navigate
131
+ url: "{{base_url}}/login"
132
+ - type: fill
133
+ selector: "input[name='email']"
134
+ value: "{{username}}"
135
+ - type: fill
136
+ selector: "input[name='password']"
137
+ value: "{{password}}"
138
+ - type: click
139
+ selector: "button[type='submit']"
140
+ - type: wait
141
+ url_contains: "/dashboard"
142
+ - type: screenshot
143
+ file: "dashboard.png"
144
+ ```
145
+
146
+ | Step | Main parameters | Purpose |
147
+ | --- | --- | --- |
148
+ | `navigate` | `url` | Open a page |
149
+ | `click`, `hover`, `press` | `selector` or `key` | Interact with an element or keyboard |
150
+ | `fill`, `type` | `selector`, `value` | Enter text |
151
+ | `select` | `selector`, one of `value` / `label` | Choose an option by HTML value or visible text |
152
+ | `wait` | selector, URL, network, or timing condition | Synchronize with dynamic UI |
153
+ | `screenshot` | `file` | Capture a page or element, optionally against a baseline |
154
+ | `check`, `uncheck` | `selector` | Control checkboxes |
155
+ | `save-state`, `load-state` | `file` | Reuse authenticated browser state |
156
+ | `if`, `loop` | condition or iteration settings | Model branches and repeated actions |
157
+ | `evaluate`, `scroll`, `set-viewport` | step-specific parameters | Run browser-side scripts or adjust the viewport |
158
+
159
+ List the available steps or inspect any step's exact parameters before writing a flow:
160
+
161
+ ```bash
162
+ pomelo-pw steps
163
+ pomelo-pw spec wait
164
+ pomelo-pw spec select
165
+ ```
166
+
167
+ The [flows/](flows/) directory contains runnable examples for waits, retries, saved state, data-driven runs, conditions, loops, JavaScript evaluation, and visual baselines. The bundled [agent skill](plugins/pomelo-pw/skills/pomelo-pw/SKILL.md) contains agent-oriented guidance and reusable flow templates.
168
+
169
+ ## Develop
170
+
171
+ Install the locked development environment:
172
+
173
+ ```bash
174
+ uv sync --all-groups --locked
175
+ ```
176
+
177
+ Run the normal quality gates directly with `uv`:
178
+
179
+ ```bash
180
+ uv run --locked --no-sync ruff format --check src tests scripts
181
+ uv run --locked --no-sync ruff check src tests scripts
182
+ uv run --locked --no-sync mypy src tests scripts
183
+ uv run --locked --no-sync pytest
184
+ ```
185
+
186
+ On systems with GNU Make and Bash, `make check` and `make test` wrap those commands. `make test cov=1` also writes an HTML coverage report.
187
+
188
+ ### Refresh the Native Plugin
189
+
190
+ The repository packages the `pomelo-pw` skill as a native plugin. Validate the package first, then refresh the editable CLI and installed plugin for available agent clients:
191
+
192
+ ```bash
193
+ uv run --locked python scripts/install.py plugin check
194
+ uv tool install --editable . --force
195
+ uv run --locked python scripts/install.py plugin apply
196
+ ```
197
+
198
+ Restart the agent client after applying a plugin update so it loads the new skill.
199
+
200
+ ### Build and Release
201
+
202
+ ```bash
203
+ # Inspect the Git-derived release version
204
+ uv run --locked --no-sync python scripts/version_calc.py
205
+
206
+ # Apply the calculated version to pyproject.toml and uv.lock
207
+ uv run --locked --no-sync python scripts/version_calc.py --no-dry-run
208
+
209
+ # Build source and wheel distributions
210
+ uv build
211
+
212
+ # Build a standalone executable when GNU Make and Bash are available
213
+ make binary
214
+ ```
215
+
216
+ Release versions are derived from Git history. After reviewing the version-file changes, commit them and create the matching `vX.Y.Z` tag; GitHub Actions builds the wheel and platform binaries from that tag.
217
+
218
+ ## Repository Layout
219
+
220
+ ```text
221
+ src/pomelo_pw/ CLI, executor, configuration, and step implementations
222
+ tests/ Unit and integration-style tests
223
+ flows/ Runnable YAML examples
224
+ plugins/pomelo-pw/ Native plugin and agent skill
225
+ docs/ Architecture and process documentation
226
+ scripts/ Plugin synchronization and release helpers
227
+ ```
228
+
229
+ ## License
230
+
231
+ MIT
@@ -0,0 +1,219 @@
1
+ # Pomelo PW
2
+
3
+ [![CI](https://github.com/leoninew/pomelo-pw/actions/workflows/ci.yml/badge.svg)](https://github.com/leoninew/pomelo-pw/actions/workflows/ci.yml)
4
+
5
+ [English](README.md) | [简体中文](README_CN.md)
6
+
7
+ Pomelo PW is a Playwright-powered CLI for browser automation. It runs declarative YAML flows, so browser checks can live alongside application code without requiring a custom test harness.
8
+
9
+ It is intended for repeatable UI checks, scripted workflows, visual comparisons, and agent-assisted browser tasks. Flows validate their parameters before execution and collect screenshots, page snapshots, console errors, and network failures when a step fails.
10
+
11
+ ## What It Provides
12
+
13
+ - YAML flows with `{{variable}}` substitution and CLI overrides
14
+ - Browser steps for navigation, forms, waits, screenshots, state reuse, conditions, and loops
15
+ - Interactive explorer and recorder for finding selectors and creating starting flows
16
+ - Step-level retries, data-driven runs, and screenshot baseline comparison
17
+ - Native plugin packaging for Claude Code, Codex, and Grok Build
18
+
19
+ ## Install
20
+
21
+ Pomelo PW requires Python 3.12+ and [uv](https://docs.astral.sh/uv/).
22
+
23
+ ```bash
24
+ # Install the published CLI, then install its browser
25
+ uv tool install pomelo-pw
26
+ pomelo-pw install
27
+
28
+ # Or invoke the published package once without installing the CLI
29
+ uvx pomelo-pw install
30
+
31
+ # Work from a source checkout
32
+ uv sync --all-groups --locked
33
+ uv run pomelo-pw install
34
+ ```
35
+
36
+ The `install` command downloads Playwright Chromium for package installations. When run from a source checkout or the standalone binary, Pomelo PW uses an installed system Chrome or Chromium when it can find one.
37
+
38
+ Install visual comparison support only when flows use screenshot baselines:
39
+
40
+ ```bash
41
+ uv pip install pillow
42
+ ```
43
+
44
+ ## Quick Start
45
+
46
+ Create `smoke.yaml`:
47
+
48
+ ```yaml
49
+ name: example-smoke
50
+ variables:
51
+ base_url: "https://example.com"
52
+
53
+ steps:
54
+ - type: navigate
55
+ url: "{{base_url}}"
56
+ - type: screenshot
57
+ file: "homepage.png"
58
+ - type: scroll
59
+ direction: down
60
+ distance: 500
61
+ - type: screenshot
62
+ file: "scrolled.png"
63
+ ```
64
+
65
+ Run and validate it:
66
+
67
+ ```bash
68
+ uvx pomelo-pw validate smoke.yaml
69
+ uvx pomelo-pw run smoke.yaml --headless
70
+ ```
71
+
72
+ Screenshots and failure artifacts are written to `./smoke/` by default. Use `-o <directory>` to choose another output directory.
73
+
74
+ ## Use Pomelo PW
75
+
76
+ ### Find Selectors and Create Flows
77
+
78
+ ```bash
79
+ # Inspect a page and copy a selector from the interactive overlay
80
+ pomelo-pw explore https://example.com
81
+
82
+ # Record clicks, fills, and Enter presses into a YAML flow
83
+ pomelo-pw record https://example.com recorded-flow.yaml
84
+ ```
85
+
86
+ Prefer selectors based on stable semantics, such as `role=button[name="Continue"]`, over presentation-oriented CSS classes.
87
+
88
+ ### Run Flows
89
+
90
+ ```bash
91
+ # Run visibly with step progress
92
+ pomelo-pw run flow.yaml -v
93
+
94
+ # Run headlessly and emit the result as JSON
95
+ pomelo-pw run flow.yaml --headless --json
96
+
97
+ # Override a flow variable for this run
98
+ pomelo-pw run flow.yaml --var base_url=https://staging.example.com
99
+
100
+ # Validate YAML and step parameters without launching a browser
101
+ pomelo-pw validate flow.yaml
102
+ ```
103
+
104
+ Variables use `{{name}}`; CLI values take precedence over step-level values, which take precedence over flow-level values. The `${name}` form is preserved for JavaScript and shell template literals.
105
+
106
+ ### Author Flows
107
+
108
+ The following flow shows the common pattern: navigate, interact, wait for a meaningful result, then capture evidence.
109
+
110
+ ```yaml
111
+ name: login-smoke
112
+ variables:
113
+ base_url: "https://app.example.com"
114
+ username: "user@example.com"
115
+ password: "secret"
116
+
117
+ steps:
118
+ - type: navigate
119
+ url: "{{base_url}}/login"
120
+ - type: fill
121
+ selector: "input[name='email']"
122
+ value: "{{username}}"
123
+ - type: fill
124
+ selector: "input[name='password']"
125
+ value: "{{password}}"
126
+ - type: click
127
+ selector: "button[type='submit']"
128
+ - type: wait
129
+ url_contains: "/dashboard"
130
+ - type: screenshot
131
+ file: "dashboard.png"
132
+ ```
133
+
134
+ | Step | Main parameters | Purpose |
135
+ | --- | --- | --- |
136
+ | `navigate` | `url` | Open a page |
137
+ | `click`, `hover`, `press` | `selector` or `key` | Interact with an element or keyboard |
138
+ | `fill`, `type` | `selector`, `value` | Enter text |
139
+ | `select` | `selector`, one of `value` / `label` | Choose an option by HTML value or visible text |
140
+ | `wait` | selector, URL, network, or timing condition | Synchronize with dynamic UI |
141
+ | `screenshot` | `file` | Capture a page or element, optionally against a baseline |
142
+ | `check`, `uncheck` | `selector` | Control checkboxes |
143
+ | `save-state`, `load-state` | `file` | Reuse authenticated browser state |
144
+ | `if`, `loop` | condition or iteration settings | Model branches and repeated actions |
145
+ | `evaluate`, `scroll`, `set-viewport` | step-specific parameters | Run browser-side scripts or adjust the viewport |
146
+
147
+ List the available steps or inspect any step's exact parameters before writing a flow:
148
+
149
+ ```bash
150
+ pomelo-pw steps
151
+ pomelo-pw spec wait
152
+ pomelo-pw spec select
153
+ ```
154
+
155
+ The [flows/](flows/) directory contains runnable examples for waits, retries, saved state, data-driven runs, conditions, loops, JavaScript evaluation, and visual baselines. The bundled [agent skill](plugins/pomelo-pw/skills/pomelo-pw/SKILL.md) contains agent-oriented guidance and reusable flow templates.
156
+
157
+ ## Develop
158
+
159
+ Install the locked development environment:
160
+
161
+ ```bash
162
+ uv sync --all-groups --locked
163
+ ```
164
+
165
+ Run the normal quality gates directly with `uv`:
166
+
167
+ ```bash
168
+ uv run --locked --no-sync ruff format --check src tests scripts
169
+ uv run --locked --no-sync ruff check src tests scripts
170
+ uv run --locked --no-sync mypy src tests scripts
171
+ uv run --locked --no-sync pytest
172
+ ```
173
+
174
+ On systems with GNU Make and Bash, `make check` and `make test` wrap those commands. `make test cov=1` also writes an HTML coverage report.
175
+
176
+ ### Refresh the Native Plugin
177
+
178
+ The repository packages the `pomelo-pw` skill as a native plugin. Validate the package first, then refresh the editable CLI and installed plugin for available agent clients:
179
+
180
+ ```bash
181
+ uv run --locked python scripts/install.py plugin check
182
+ uv tool install --editable . --force
183
+ uv run --locked python scripts/install.py plugin apply
184
+ ```
185
+
186
+ Restart the agent client after applying a plugin update so it loads the new skill.
187
+
188
+ ### Build and Release
189
+
190
+ ```bash
191
+ # Inspect the Git-derived release version
192
+ uv run --locked --no-sync python scripts/version_calc.py
193
+
194
+ # Apply the calculated version to pyproject.toml and uv.lock
195
+ uv run --locked --no-sync python scripts/version_calc.py --no-dry-run
196
+
197
+ # Build source and wheel distributions
198
+ uv build
199
+
200
+ # Build a standalone executable when GNU Make and Bash are available
201
+ make binary
202
+ ```
203
+
204
+ Release versions are derived from Git history. After reviewing the version-file changes, commit them and create the matching `vX.Y.Z` tag; GitHub Actions builds the wheel and platform binaries from that tag.
205
+
206
+ ## Repository Layout
207
+
208
+ ```text
209
+ src/pomelo_pw/ CLI, executor, configuration, and step implementations
210
+ tests/ Unit and integration-style tests
211
+ flows/ Runnable YAML examples
212
+ plugins/pomelo-pw/ Native plugin and agent skill
213
+ docs/ Architecture and process documentation
214
+ scripts/ Plugin synchronization and release helpers
215
+ ```
216
+
217
+ ## License
218
+
219
+ MIT
@@ -0,0 +1,69 @@
1
+ [project]
2
+ name = "pomelo-pw"
3
+ version = "0.15.4"
4
+ description = "Flow-based UI automation tool powered by Playwright"
5
+ readme = "README.md"
6
+ requires-python = ">=3.12"
7
+ dependencies = [
8
+ "playwright>=1.40.0",
9
+ "click>=8.0.0",
10
+ "pyyaml>=6.0",
11
+ ]
12
+
13
+ [project.optional-dependencies]
14
+ visual = [
15
+ "pillow>=10.0.0",
16
+ ]
17
+
18
+ [project.scripts]
19
+ pomelo-pw = "pomelo_pw.__main__:main"
20
+
21
+ [build-system]
22
+ requires = ["hatchling"]
23
+ build-backend = "hatchling.build"
24
+
25
+ [tool.hatch.build.targets.wheel]
26
+ packages = ["src/pomelo_pw"]
27
+
28
+ [tool.hatch.build.targets.sdist]
29
+ include = ["src/pomelo_pw"]
30
+
31
+ [dependency-groups]
32
+ dev = [
33
+ "pyinstaller>=6.18.0",
34
+ "ruff>=0.15.17",
35
+ "mypy>=2.1.0",
36
+ "pytest>=9.0.2",
37
+ "types-pyyaml>=6.0.12.20260518",
38
+ "pytest-asyncio>=1.4.0",
39
+ "pytest-cov>=7.0.0,<8.0.0",
40
+ ]
41
+
42
+ [tool.mypy]
43
+ python_version = "3.12"
44
+ files = ["src", "tests", "scripts"]
45
+ mypy_path = "src"
46
+ strict = true
47
+ warn_return_any = true
48
+ warn_unused_configs = true
49
+ warn_unreachable = true
50
+ pretty = true
51
+
52
+ [tool.ruff]
53
+ line-length = 120
54
+ target-version = "py312"
55
+ exclude = ["scripts/install.py"]
56
+ force-exclude = true
57
+
58
+ [tool.ruff.format]
59
+ quote-style = "double"
60
+ indent-style = "space"
61
+ line-ending = "auto"
62
+
63
+ [tool.ruff.lint]
64
+ select = ["E", "F", "I", "UP", "B", "SIM"]
65
+ ignore = ["E501"]
66
+
67
+ [tool.pytest.ini_options]
68
+ asyncio_mode = "auto"
69
+ testpaths = ["tests"]
@@ -0,0 +1,5 @@
1
+ """Pomelo PW - Flow-based UI Automation Tool."""
2
+
3
+ from importlib.metadata import version
4
+
5
+ __version__ = version("pomelo-pw")
@@ -0,0 +1,12 @@
1
+ """Executable entry point for Pomelo PW."""
2
+
3
+ from pomelo_pw.cli import cli
4
+
5
+
6
+ def main() -> None:
7
+ """Run the command-line interface."""
8
+ cli()
9
+
10
+
11
+ if __name__ == "__main__":
12
+ main()
@@ -0,0 +1,36 @@
1
+ """Shared Playwright browser setup."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Any
6
+
7
+ from playwright.async_api import Browser, BrowserContext, Playwright
8
+
9
+ from pomelo_pw.config import PlaywrightConfig
10
+
11
+
12
+ class BrowserLifecycle:
13
+ """Create browser resources from the resolved Playwright configuration."""
14
+
15
+ def __init__(self, config: PlaywrightConfig) -> None:
16
+ self.config = config
17
+
18
+ async def launch(self, playwright: Playwright, *, headless: bool) -> Browser:
19
+ """Launch Chromium with the configured runtime options."""
20
+ launch_options: dict[str, Any] = {
21
+ "headless": headless,
22
+ "timeout": self.config.timeout,
23
+ "slow_mo": self.config.slow_mo,
24
+ }
25
+ if self.config.executable_path:
26
+ launch_options["executable_path"] = self.config.executable_path
27
+ return await playwright.chromium.launch(**launch_options)
28
+
29
+ async def new_context(self, browser: Browser) -> BrowserContext:
30
+ """Create a browser context with the configured viewport."""
31
+ return await browser.new_context(
32
+ viewport={
33
+ "width": self.config.viewport.width,
34
+ "height": self.config.viewport.height,
35
+ },
36
+ )