MarketSquare / MarketSquare/robotframework-browser

Screenshots and traces are written into site-packages when keywords are called from Python outside a Robot Framework run

Open
#5,151 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug
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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.