|
3 | 3 | # https://playwright.dev/ |
4 | 4 | # |
5 | 5 | import json |
| 6 | +import os |
6 | 7 | from typing import Dict, Generator, List |
| 8 | +from pathlib import Path |
7 | 9 |
|
8 | 10 | import click |
9 | 11 | from junitparser import TestCase, TestSuite # type: ignore |
@@ -173,13 +175,54 @@ def parse_func(self, report_file: str) -> Generator[CaseEvent, None, None]: |
173 | 175 | click.echo("Can't find test results from {}. Make sure to confirm report file.".format( |
174 | 176 | report_file), err=True) |
175 | 177 |
|
| 178 | + test_prefix = self._compute_test_prefix(data) |
176 | 179 | for s in suites: |
177 | 180 | # The title of the root suite object contains the file name. |
178 | | - test_file = str(s.get("title", "")) |
| 181 | + test_file = self._resolve_test_file(str(s.get("title", "")), test_prefix) |
179 | 182 |
|
180 | 183 | for event in self._parse_suites(test_file, s, []): |
181 | 184 | yield event |
182 | 185 |
|
| 186 | + def _compute_test_prefix(self, report: Dict) -> str: |
| 187 | + """ |
| 188 | + Playwright JSON stores test `file` paths relative to `config.rootDir`. |
| 189 | + Our CLI wants paths relative to the Playwright config directory |
| 190 | + (usually the project/repo root), so we compute: |
| 191 | + relpath(root_dir, base_dir) |
| 192 | + where base_dir = dirname(configFile). |
| 193 | +
|
| 194 | + Example: |
| 195 | + configFile = /repo/playwright.config.ts |
| 196 | + rootDir = /repo/tests |
| 197 | + relpath(...) -> "tests" |
| 198 | + """ |
| 199 | + config: Dict = report.get("config", {}) |
| 200 | + config_file = str(config.get("configFile", "")) |
| 201 | + root_dir = str(config.get("rootDir", "")) |
| 202 | + if not config_file or not root_dir: |
| 203 | + return "" |
| 204 | + |
| 205 | + base_dir = Path(config_file).parent |
| 206 | + try: |
| 207 | + test_prefix = Path(root_dir).relative_to(base_dir).as_posix() |
| 208 | + except ValueError: |
| 209 | + return "" |
| 210 | + |
| 211 | + if test_prefix == ".": |
| 212 | + return "" |
| 213 | + |
| 214 | + return test_prefix |
| 215 | + |
| 216 | + def _resolve_test_file(self, test_file: str, test_prefix: str) -> str: |
| 217 | + if not test_prefix or not test_file: |
| 218 | + return test_file |
| 219 | + |
| 220 | + # Guard against duplicate paths when report data is already prefixed. |
| 221 | + if test_file.startswith(test_prefix): |
| 222 | + return test_file |
| 223 | + |
| 224 | + return Path(test_prefix, test_file).as_posix() |
| 225 | + |
183 | 226 | def _parse_suites(self, test_file: str, suite: Dict[str, Dict], test_case_names: List[str] = []) -> List: |
184 | 227 | events = [] |
185 | 228 |
|
|
0 commit comments