MarketSquare / MarketSquare/robotframework-browser
Screenshots and traces are written into site-packages when keywords are called from Python outside a Robot Framework run
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 655
- Forks
- 147
- Avg merge
- 5h 27m
- Merged PRs (30d)
- 59
Description
When keywords are called directly from Python, without a Robot Framework run, `outputdir` is the **relative** string `"."` (`Browser/browser.py:455`). Artefacts whose paths are handed to the Node side as relative strings are then resolved against the Node process's working directory, which is the wrapper directory — so they land inside the installed package instead of the user's working directory.
Under a `robot` run this cannot happen: `outputdir` comes from `${OUTPUTDIR}` and is absolute. Verified.
### Reproduce
```python
from Browser import Browser
browser = Browser()
browser.new_browser("webkit", headless=True)
browser.new_page("https://robotframework-browser.org")
print(browser.take_screenshot())
browser.close_browser("ALL")
```
Observed:
```
browser/screenshot/robotframework-browser-screenshot-1.png <- returned path
```
* The returned path is relative and **does not exist** relative to the caller's working directory.
* An **empty** `./browser/screenshot/` is created in the caller's working directory by the Python side.
* The actual PNG is written to `/Browser/wrapper/browser/screenshot/robotframework-browser-screenshot-1.png`.
### The rule
Anything Python resolves to an absolute path before sending it over gRPC is fine. Anything sent as a relative string is resolved by Node against `Browser/wrapper`.
**Affected**
| Artefact | Source |
| --- | --- |
| Screenshots | returned path is relative and wrong |
| `tracing=True` trace zip | `Browser/keywords/playwright_state.py:874-877` — no `.resolve()` |
| Trace `temp//` working files | `Browser/keywords/playwright_state.py:911` |
| `Save Storage State` | `Browser/keywords/playwright_state.py:1720-1722` — from source, not run |
| Node V8 coverage output | `Browser/playwright.py:96` — from source, not run |
**Not affected**
| Artefact | Why |
| --- | --- |
| `playwright-log.txt` | opened by Python itself, `Browser/playwright.py:234-235` |
| Video | explicitly resolved, `Browser/keywords/playwright_state.py:948-960` |
An explicit `tracing=Path("x.zip")` is also fine — lines 878-880 do resolve it. Only the `tracing=True` path is affected.
### Cause
`Browser/browser.py:455` sets `_output_dir = "."`, and `Browser/browser.py:795-798` returns it unchanged when there is no execution context. The Node process is started with `cwd=self._browser_wrapper_dir` (`Browser/playwright.py:280`, passed to `Popen` at `:104`).
### Possible fix
Making the default absolute at construction time was probed in-process (`Browser._output_dir = str(Path.cwd())` before constructing). It fixes the screenshot path, the trace zip and the trace temp directory, makes the returned paths absolute, and moves nothing to a new wrong place. It does **not** fix `recordHar`, which never passes through `outputdir` at all — filed separately.
### Environment
Browser 20.3.0, Robot Framework 7.4.1, Python 3.14.7, macOS, webkit.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with Browser/browser.py:455 and 795-798, then inspect the affected artifact paths in Browser/keywords/playwright_state.py and Browser/playwright.py. Run the provided direct-Python reproduction and verify that screenshots, tracing outputs, trace temporary files, storage state, and coverage use the caller's working directory without changing the explicitly resolved or unaffected artifacts.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- playwright, python
- Domain
- testing-qa, tooling
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 75/100