Skip to content

Commit d342099

Browse files
authored
feat: expose output_path fixture (#248)
1 parent 635b2c2 commit d342099

File tree

2 files changed

+75
-22
lines changed

2 files changed

+75
-22
lines changed

pytest_playwright/pytest_playwright.py

+17-19
Original file line numberDiff line numberDiff line change
@@ -180,15 +180,10 @@ def _is_debugger_attached() -> bool:
180180
return debugger.is_attached()
181181

182182

183-
def _build_artifact_test_folder(
184-
pytestconfig: Any, request: pytest.FixtureRequest, folder_or_file_name: str
185-
) -> str:
186-
output_dir = pytestconfig.getoption("--output")
187-
return os.path.join(
188-
output_dir,
189-
_truncate_file_name(slugify(request.node.nodeid)),
190-
_truncate_file_name(folder_or_file_name),
191-
)
183+
@pytest.fixture
184+
def output_path(pytestconfig: Any, request: pytest.FixtureRequest) -> str:
185+
output_dir = Path(pytestconfig.getoption("--output")).absolute()
186+
return os.path.join(output_dir, _truncate_file_name(slugify(request.node.nodeid)))
192187

193188

194189
def _truncate_file_name(file_name: str) -> str:
@@ -222,12 +217,13 @@ def browser_context_args(
222217
@pytest.fixture()
223218
def _artifacts_recorder(
224219
request: pytest.FixtureRequest,
220+
output_path: str,
225221
playwright: Playwright,
226222
pytestconfig: Any,
227223
_pw_artifacts_folder: tempfile.TemporaryDirectory,
228224
) -> Generator["ArtifactsRecorder", None, None]:
229225
artifacts_recorder = ArtifactsRecorder(
230-
pytestconfig, request, playwright, _pw_artifacts_folder
226+
pytestconfig, request, output_path, playwright, _pw_artifacts_folder
231227
)
232228
yield artifacts_recorder
233229
# If request.node is missing rep_call, then some error happened during execution
@@ -462,12 +458,14 @@ def __init__(
462458
self,
463459
pytestconfig: Any,
464460
request: pytest.FixtureRequest,
461+
output_path: str,
465462
playwright: Playwright,
466463
pw_artifacts_folder: tempfile.TemporaryDirectory,
467464
) -> None:
468465
self._request = request
469466
self._pytestconfig = pytestconfig
470467
self._playwright = playwright
468+
self._output_path = output_path
471469
self._pw_artifacts_folder = pw_artifacts_folder
472470

473471
self._all_pages: List[Page] = []
@@ -476,6 +474,12 @@ def __init__(
476474
self._tracing_option = pytestconfig.getoption("--tracing")
477475
self._capture_trace = self._tracing_option in ["on", "retain-on-failure"]
478476

477+
def _build_artifact_test_folder(self, folder_or_file_name: str) -> str:
478+
return os.path.join(
479+
self._output_path,
480+
_truncate_file_name(folder_or_file_name),
481+
)
482+
479483
def did_finish_test(self, failed: bool) -> None:
480484
screenshot_option = self._pytestconfig.getoption("--screenshot")
481485
capture_screenshot = screenshot_option == "on" or (
@@ -484,9 +488,7 @@ def did_finish_test(self, failed: bool) -> None:
484488
if capture_screenshot:
485489
for index, screenshot in enumerate(self._screenshots):
486490
human_readable_status = "failed" if failed else "finished"
487-
screenshot_path = _build_artifact_test_folder(
488-
self._pytestconfig,
489-
self._request,
491+
screenshot_path = self._build_artifact_test_folder(
490492
f"test-{human_readable_status}-{index+1}.png",
491493
)
492494
os.makedirs(os.path.dirname(screenshot_path), exist_ok=True)
@@ -502,9 +504,7 @@ def did_finish_test(self, failed: bool) -> None:
502504
trace_file_name = (
503505
"trace.zip" if len(self._traces) == 1 else f"trace-{index+1}.zip"
504506
)
505-
trace_path = _build_artifact_test_folder(
506-
self._pytestconfig, self._request, trace_file_name
507-
)
507+
trace_path = self._build_artifact_test_folder(trace_file_name)
508508
os.makedirs(os.path.dirname(trace_path), exist_ok=True)
509509
shutil.move(trace, trace_path)
510510
else:
@@ -527,9 +527,7 @@ def did_finish_test(self, failed: bool) -> None:
527527
else f"video-{index+1}.webm"
528528
)
529529
video.save_as(
530-
path=_build_artifact_test_folder(
531-
self._pytestconfig, self._request, video_file_name
532-
)
530+
path=self._build_artifact_test_folder(video_file_name)
533531
)
534532
except Error:
535533
# Silent catch empty videos.

tests/test_playwright.py

+58-3
Original file line numberDiff line numberDiff line change
@@ -644,14 +644,18 @@ def test_passing(page):
644644
def test_artifacts_should_store_everything_if_on(testdir: pytest.Testdir) -> None:
645645
testdir.makepyfile(
646646
"""
647-
def test_passing(page):
647+
def test_passing(page, output_path):
648+
print(f"\\n\\noutput_path = {output_path}\\n\\n")
648649
assert 2 == page.evaluate("1 + 1")
649650
650-
def test_failing(page):
651+
def test_failing(page, output_path):
652+
print(f"\\n\\noutput_path = {output_path}\\n\\n")
651653
raise Exception("Failed")
652654
"""
653655
)
654-
result = testdir.runpytest("--screenshot", "on", "--video", "on", "--tracing", "on")
656+
result = testdir.runpytest(
657+
"--screenshot", "on", "--video", "on", "--tracing", "on", "-s"
658+
)
655659
result.assert_outcomes(passed=1, failed=1)
656660
test_results_dir = os.path.join(testdir.tmpdir, "test-results")
657661
_assert_folder_structure(
@@ -667,6 +671,18 @@ def test_failing(page):
667671
- video.webm
668672
""",
669673
)
674+
output_path = str(testdir.tmpdir)
675+
output_paths = [
676+
line[14:] for line in result.outlines if f"output_path = {output_path}" in line
677+
]
678+
assert output_paths == [
679+
testdir.tmpdir.join(
680+
"test-results/test-artifacts-should-store-everything-if-on-py-test-passing-chromium"
681+
).strpath,
682+
testdir.tmpdir.join(
683+
"test-results/test-artifacts-should-store-everything-if-on-py-test-failing-chromium"
684+
).strpath,
685+
]
670686

671687

672688
def test_artifacts_retain_on_failure(testdir: pytest.Testdir) -> None:
@@ -912,3 +928,42 @@ def test_artifact_collection(new_context):
912928
)
913929
result = testdir.runpytest()
914930
result.assert_outcomes(passed=1)
931+
932+
933+
def test_output_path_via_pytest_runtest_makereport_hook(
934+
testdir: pytest.Testdir,
935+
) -> None:
936+
testdir.makeconftest(
937+
"""
938+
import pytest
939+
940+
@pytest.hookimpl(hookwrapper=True)
941+
def pytest_runtest_makereport(item, call):
942+
outcome = yield
943+
report = outcome.get_result()
944+
945+
if report.when == "call":
946+
output_path = item.funcargs.get("output_path")
947+
print("\\n\\noutput_path = {}".format(output_path))
948+
"""
949+
)
950+
951+
testdir.makepyfile(
952+
"""
953+
def test_without_output_path():
954+
pass
955+
956+
def test_with_page(page):
957+
pass
958+
"""
959+
)
960+
961+
result = testdir.runpytest("--screenshot", "on", "-s")
962+
result.assert_outcomes(passed=2)
963+
output_paths = [line[14:] for line in result.outlines if "output_path = " in line]
964+
assert output_paths == [
965+
"None",
966+
testdir.tmpdir.join(
967+
"test-results/test-output-path-via-pytest-runtest-makereport-hook-py-test-with-page-chromium"
968+
).strpath,
969+
]

0 commit comments

Comments
 (0)