diff --git a/atest/test/01_Browser_Management/tracing_groups.py b/atest/library/tracing_groups.py
similarity index 54%
rename from atest/test/01_Browser_Management/tracing_groups.py
rename to atest/library/tracing_groups.py
index 593a3896b..a9968350b 100644
--- a/atest/test/01_Browser_Management/tracing_groups.py
+++ b/atest/library/tracing_groups.py
@@ -1,9 +1,9 @@
import json
from pathlib import Path
-from typing import Union
def get_trace_lines(path: Path) -> list[dict]:
+ """Returns the ``before`` entries of a Playwright trace file."""
with path.open(encoding="utf-8") as file:
return [
json.loads(line) for line in file.readlines() if '"type":"before"' in line
@@ -11,6 +11,7 @@ def get_trace_lines(path: Path) -> list[dict]:
def get_trace_group_titles(path: Path) -> list[str]:
+ """Returns the titles of the trace groups in a Playwright trace file, in order."""
return [
line["title"]
for line in get_trace_lines(path)
@@ -18,8 +19,9 @@ def get_trace_group_titles(path: Path) -> list[str]:
]
-def get_file_line(file: Union[Path, None], line: int, column: int) -> str:
+def get_file_line(file: Path | None, line: int, column: int) -> str | None:
+ """Returns line ``line`` of ``file``, or ``None`` without a file."""
if file is None:
return None
- with file.open(encoding="utf-8") as file:
- return file.readlines()[line - 1]
+ with file.open(encoding="utf-8") as source:
+ return source.readlines()[line - 1]
diff --git a/atest/test/01_Browser_Management/tracing_groups.robot b/atest/test/01_Browser_Management/tracing_groups.robot
index 98914f3a0..22563127c 100644
--- a/atest/test/01_Browser_Management/tracing_groups.robot
+++ b/atest/test/01_Browser_Management/tracing_groups.robot
@@ -3,7 +3,7 @@ Resource ../variables.resource
Library Browser auto_delete_passed_tracing=True tracing_group_mode=Full
Library OperatingSystem
Library ArchiveLibrary
-Library tracing_groups.py
+Library ../../library/tracing_groups.py
Library Collections
*** Variables ***
diff --git a/atest/test/05_JS_Tests/adopted_context_recording.robot b/atest/test/05_JS_Tests/adopted_context_recording.robot
index be2adb035..6cd574575 100644
--- a/atest/test/05_JS_Tests/adopted_context_recording.robot
+++ b/atest/test/05_JS_Tests/adopted_context_recording.robot
@@ -3,7 +3,7 @@ Library ../../library/AdoptingLibrary.py jsextension=${CURDIR}/adopt.js
Library ArchiveLibrary
Library Collections
Library OperatingSystem
-Library ../01_Browser_Management/tracing_groups.py
+Library ../../library/tracing_groups.py
Resource ../variables.resource
Test Tags no-iframe
diff --git a/utest/test_adopted_context.py b/utest/test_adopted_context.py
index b240283e7..7dc1706e4 100644
--- a/utest/test_adopted_context.py
+++ b/utest/test_adopted_context.py
@@ -25,7 +25,8 @@ def grpc_channel(self):
yield self.stub
-def library(tmpdir, monkeypatch) -> Browser:
+@pytest.fixture
+def browser(tmpdir, monkeypatch) -> Browser:
monkeypatch.setattr(Browser, "_output_dir", tmpdir)
monkeypatch.setattr(Browser, "_context_cache", ContextCache())
monkeypatch.delenv("ROBOT_FRAMEWORK_BROWSER_TRACING", raising=False)
@@ -34,17 +35,26 @@ def library(tmpdir, monkeypatch) -> Browser:
return browser
+VIEWPORT = {"width": 800, "height": 600}
+VIDEO_SIZES = [
+ ({}, {"width": 800, "height": 600}),
+ ({"size": {"width": 640, "height": 480}}, {"width": 640, "height": 480}),
+]
+
+
def keyword_call(name: str) -> KeywordCallStackEntry:
return {"name": name, "file": "", "line": 0, "kwname": name, "args": []}
-def sent_options(request) -> dict:
- return json.loads(request.call_args.args[0].rawOptions)
+def sent_request(stub_method):
+ return stub_method.call_args.args[0]
-def test_no_tracing_and_no_recording_by_default(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
+def sent_options(stub_method) -> dict:
+ return json.loads(sent_request(stub_method).rawOptions)
+
+def test_no_tracing_and_no_recording_by_default(browser: Browser):
options = browser.adopted_context_options()
assert options["tracing"] is None
@@ -53,10 +63,8 @@ def test_no_tracing_and_no_recording_by_default(tmpdir, monkeypatch):
def test_traces_dir_is_a_new_folder_in_browsers_temporary_trace_folder(
- tmpdir, monkeypatch
+ browser: Browser,
):
- browser = library(tmpdir, monkeypatch)
-
first = browser.adopted_context_options()["tracesDir"]
second = browser.adopted_context_options()["tracesDir"]
@@ -64,9 +72,7 @@ def test_traces_dir_is_a_new_folder_in_browsers_temporary_trace_folder(
assert first != second
-def test_tracing_follows_new_context(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
-
+def test_tracing_follows_new_context(browser: Browser, tmpdir):
assert browser.adopted_context_options(tracing=True)["tracing"] == str(
browser.traces_output
)
@@ -75,23 +81,19 @@ def test_tracing_follows_new_context(tmpdir, monkeypatch):
)
-def test_relative_trace_folder_is_in_browsers_trace_folder(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
-
+def test_relative_trace_folder_is_in_browsers_trace_folder(browser: Browser):
options = browser.adopted_context_options(tracing=Path("adopted"))
assert options["tracing"] == str((browser.traces_output / "adopted").resolve())
-def test_tracing_follows_the_global_setting(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
+def test_tracing_follows_the_global_setting(browser: Browser, monkeypatch):
monkeypatch.setenv("ROBOT_FRAMEWORK_BROWSER_TRACING", "True")
assert browser.adopted_context_options()["tracing"] == str(browser.traces_output)
-def test_tracing_follows_the_robot_framework_variable(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
+def test_tracing_follows_the_robot_framework_variable(browser: Browser, monkeypatch):
variables = {"${ROBOT_FRAMEWORK_BROWSER_TRACING}": "True"}
monkeypatch.setattr(
"Browser.keywords.playwright_state.EXECUTION_CONTEXTS",
@@ -105,9 +107,7 @@ def test_tracing_follows_the_robot_framework_variable(tmpdir, monkeypatch):
assert browser.adopted_context_options()["tracing"] == str(browser.traces_output)
-def test_empty_video_options_record_with_the_defaults(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
-
+def test_empty_video_options_record_with_the_defaults(browser: Browser):
options = browser.adopted_context_options(recordVideo={})
assert options["recordVideo"] == {
@@ -116,9 +116,7 @@ def test_empty_video_options_record_with_the_defaults(tmpdir, monkeypatch):
}
-def test_video_keeps_its_other_keys(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
-
+def test_video_keeps_its_other_keys(browser: Browser):
options = browser.adopted_context_options(
recordVideo={"showActions": {"duration": 500}}
)
@@ -126,9 +124,7 @@ def test_video_keeps_its_other_keys(tmpdir, monkeypatch):
assert options["recordVideo"]["showActions"] == {"duration": 500}
-def test_video_options_are_converted_like_new_context(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
-
+def test_video_options_are_converted_like_new_context(browser: Browser):
options = browser.adopted_context_options(
recordVideo={"fps": "10", "showActions": {"duration": "300"}}
)
@@ -137,16 +133,12 @@ def test_video_options_are_converted_like_new_context(tmpdir, monkeypatch):
assert options["recordVideo"]["showActions"] == {"duration": 300}
-def test_deprecated_font_size_fails_like_new_context(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
-
+def test_deprecated_font_size_fails_like_new_context(browser: Browser):
with pytest.raises(ValueError, match="RecordVideo"):
browser.adopted_context_options(recordVideo={"showActions": {"fontSize": 20}})
-def test_video_folder_and_size_follow_new_context(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
-
+def test_video_folder_and_size_follow_new_context(browser: Browser):
options = browser.adopted_context_options(
recordVideo={"dir": "demo", "size": {"width": "800", "height": "600"}}
)
@@ -157,8 +149,7 @@ def test_video_folder_and_size_follow_new_context(tmpdir, monkeypatch):
}
-def test_absolute_video_folder_is_kept(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
+def test_absolute_video_folder_is_kept(browser: Browser, tmpdir):
videos = str(Path(tmpdir, "elsewhere", "videos").resolve())
options = browser.adopted_context_options(recordVideo={"dir": videos})
@@ -166,9 +157,7 @@ def test_absolute_video_folder_is_kept(tmpdir, monkeypatch):
assert options["recordVideo"]["dir"] == videos
-def test_video_without_size_has_the_size_of_the_viewport(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
-
+def test_video_without_size_has_the_size_of_the_viewport(browser: Browser):
options = browser.adopted_context_options(
recordVideo={}, viewport={"width": 1024, "height": 768}
)
@@ -176,8 +165,7 @@ def test_video_without_size_has_the_size_of_the_viewport(tmpdir, monkeypatch):
assert options["recordVideo"]["size"] == {"width": 1024, "height": 768}
-def test_registered_context_gets_the_keyword_calls_as_trace_groups(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
+def test_registered_context_gets_the_keyword_calls_as_trace_groups(browser: Browser):
browser.keyword_call_stack.append(keyword_call("Open Application"))
options = browser.adopted_context_options(tracing=True)
@@ -188,8 +176,7 @@ def test_registered_context_gets_the_keyword_calls_as_trace_groups(tmpdir, monke
assert browser.tracing_contexts == ["context=1"]
-def test_registered_context_without_tracing_gets_no_trace_groups(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
+def test_registered_context_without_tracing_gets_no_trace_groups(browser: Browser):
browser.keyword_call_stack.append(keyword_call("Open Application"))
browser.register_adopted_context("context=1", browser.adopted_context_options())
@@ -198,8 +185,7 @@ def test_registered_context_without_tracing_gets_no_trace_groups(tmpdir, monkeyp
assert browser.tracing_contexts == []
-def test_playwright_tracing_group_mode_adds_no_trace_groups(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
+def test_playwright_tracing_group_mode_adds_no_trace_groups(browser: Browser):
browser.tracing_group_mode = TracingGroupMode.Playwright
browser.keyword_call_stack.append(keyword_call("Open Application"))
options = browser.adopted_context_options(tracing=True)
@@ -211,9 +197,8 @@ def test_playwright_tracing_group_mode_adds_no_trace_groups(tmpdir, monkeypatch)
def test_registered_context_outside_a_keyword_is_traced_without_trace_groups(
- tmpdir, monkeypatch
+ browser: Browser,
):
- browser = library(tmpdir, monkeypatch)
browser.tracing_group_mode = TracingGroupMode.Browser
options = browser.adopted_context_options(tracing=True)
@@ -223,22 +208,21 @@ def test_registered_context_outside_a_keyword_is_traced_without_trace_groups(
assert browser.tracing_contexts == ["context=1"]
-def test_registered_context_embeds_its_video(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
- options = browser.adopted_context_options(recordVideo={})
+def test_registered_context_embeds_its_video(browser: Browser, caplog):
+ caplog.set_level("INFO")
+ options = browser.adopted_context_options(recordVideo={}, viewport=VIEWPORT)
video = str(Path(options["recordVideo"]["dir"], "page.webm"))
video_path = browser.register_adopted_context("context=1", options, video)
assert video_path == video
- assert browser._playwright_state.context_cache.get("context=1") == {
- "width": 1280,
- "height": 720,
- }
+ assert (
+ ''
+ ) in caplog.text
-def test_video_path_without_record_video_is_ignored(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
+def test_video_path_without_record_video_is_ignored(browser: Browser):
options = browser.adopted_context_options()
video_path = browser.register_adopted_context("context=1", options, "page.webm")
@@ -246,9 +230,9 @@ def test_video_path_without_record_video_is_ignored(tmpdir, monkeypatch):
assert video_path == ""
-def test_relative_har_path_is_relative_to_the_output_directory(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
-
+def test_relative_har_path_is_relative_to_the_output_directory(
+ browser: Browser, tmpdir
+):
options = browser.adopted_context_options(
recordHar={"path": "har/app.har", "omitContent": True}
)
@@ -259,8 +243,7 @@ def test_relative_har_path_is_relative_to_the_output_directory(tmpdir, monkeypat
}
-def test_absolute_har_path_is_kept(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
+def test_absolute_har_path_is_kept(browser: Browser, tmpdir):
har = str(Path(tmpdir, "elsewhere", "app.har").resolve())
options = browser.adopted_context_options(recordHar={"path": har})
@@ -268,18 +251,14 @@ def test_absolute_har_path_is_kept(tmpdir, monkeypatch):
assert options["recordHar"] == {"path": har}
-def test_new_context_resolves_a_relative_har_path(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
-
+def test_new_context_resolves_a_relative_har_path(browser: Browser, tmpdir):
browser.new_context(recordHar={"path": "context.har"})
options = sent_options(browser._playwright.stub.NewContext)
assert options["recordHar"] == {"path": str(Path(tmpdir, "context.har").resolve())}
-def test_new_persistent_context_resolves_a_relative_har_path(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
-
+def test_new_persistent_context_resolves_a_relative_har_path(browser: Browser, tmpdir):
browser.new_persistent_context(recordHar={"path": "persistent.har"})
options = sent_options(browser._playwright.stub.NewPersistentContext)
@@ -288,8 +267,7 @@ def test_new_persistent_context_resolves_a_relative_har_path(tmpdir, monkeypatch
}
-def test_new_context_sends_frame_rate_and_action_annotations(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
+def test_new_context_sends_frame_rate_and_action_annotations(browser: Browser):
show_actions = {
"duration": 300,
"position": "bottom-left",
@@ -304,9 +282,7 @@ def test_new_context_sends_frame_rate_and_action_annotations(tmpdir, monkeypatch
assert options["recordVideo"]["showActions"] == show_actions
-def test_new_persistent_context_sends_action_annotations(tmpdir, monkeypatch):
- browser = library(tmpdir, monkeypatch)
-
+def test_new_persistent_context_sends_action_annotations(browser: Browser):
browser.new_persistent_context(recordVideo={"showActions": {"position": "top"}})
options = sent_options(browser._playwright.stub.NewPersistentContext)
@@ -325,10 +301,9 @@ def persistent_context_with_video(browser: Browser) -> MagicMock:
def test_new_persistent_context_caches_and_embeds_its_video_once_its_url_opened(
- tmpdir, monkeypatch, caplog
+ browser: Browser, caplog
):
caplog.set_level("INFO")
- browser = library(tmpdir, monkeypatch)
persistent_context_with_video(browser)
browser.new_persistent_context(url="http://localhost:1", recordVideo={})
@@ -340,8 +315,7 @@ def test_new_persistent_context_caches_and_embeds_its_video_once_its_url_opened(
assert "