RemiFabre commited on
Commit
9edf0fd
·
1 Parent(s): 2a6e555

Fix test coverage merging: seed from test_coverage.json on first run

Browse files

test_results.json is git-ignored (local to each machine). When a new
contributor ran tests, their empty file caused export_web_coverage() to
overwrite test_coverage.json with only their results, erasing other
testers' data.

Now load_results() seeds from the committed test_coverage.json when
test_results.json is missing or empty, so the next export merges
results from all contributors. Same fix applied to show_matrix.py.

Files changed (2) hide show
  1. tests/run_tests.py +48 -1
  2. tests/show_matrix.py +40 -7
tests/run_tests.py CHANGED
@@ -216,8 +216,55 @@ def check_json_report_plugin() -> bool:
216
 
217
 
218
  def load_results() -> list[dict]:
 
 
 
 
 
 
 
 
219
  if RESULTS_FILE.exists():
220
- return json.loads(RESULTS_FILE.read_text())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
221
  return []
222
 
223
 
 
216
 
217
 
218
  def load_results() -> list[dict]:
219
+ """Load past results from test_results.json, seeding from test_coverage.json if needed.
220
+
221
+ test_results.json is git-ignored (local to each machine). When a new
222
+ contributor runs for the first time, their file is empty — but the
223
+ committed test_coverage.json contains the matrix from other testers.
224
+ We import those entries so the next export *merges* instead of
225
+ overwriting.
226
+ """
227
  if RESULTS_FILE.exists():
228
+ try:
229
+ data = json.loads(RESULTS_FILE.read_text())
230
+ if data:
231
+ return data
232
+ except (json.JSONDecodeError, ValueError):
233
+ pass
234
+
235
+ # Seed from the committed web coverage file so we don't lose other
236
+ # contributors' results on first run.
237
+ if WEB_COVERAGE_FILE.exists():
238
+ try:
239
+ coverage = json.loads(WEB_COVERAGE_FILE.read_text())
240
+ entries = coverage.get("matrix", [])
241
+ if entries:
242
+ # Convert matrix entries back to results-like dicts.
243
+ # The matrix has: os, robot, suite, browser, status,
244
+ # passed, failed, total, date. We synthesise a
245
+ # timestamp from the generated_at field so the
246
+ # "latest per combo" logic still works.
247
+ generated = coverage.get("generated_at", datetime.now(timezone.utc).isoformat())
248
+ seeded = []
249
+ for e in entries:
250
+ seeded.append({
251
+ "timestamp": generated,
252
+ "os": e["os"],
253
+ "robot": e["robot"],
254
+ "suite": e["suite"],
255
+ "browser": e.get("browser"),
256
+ "passed": e.get("passed", 0),
257
+ "failed": e.get("failed", 0),
258
+ "errors": 0,
259
+ "total": e.get("total", 0),
260
+ "status": e.get("status", "pass"),
261
+ "returncode": 0,
262
+ })
263
+ print(f"Seeded {len(seeded)} entries from {WEB_COVERAGE_FILE.name}")
264
+ return seeded
265
+ except (json.JSONDecodeError, ValueError):
266
+ pass
267
+
268
  return []
269
 
270
 
tests/show_matrix.py CHANGED
@@ -122,15 +122,48 @@ def print_catalog(catalog: list[dict]) -> None:
122
  print()
123
 
124
 
125
- def main() -> None:
126
- if not RESULTS_FILE.exists():
127
- print(f"No results file found at {RESULTS_FILE}")
128
- print("Run tests first: python tests/run_tests.py")
129
- sys.exit(1)
 
 
 
 
130
 
131
- results = json.loads(RESULTS_FILE.read_text())
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  if not results:
133
- print("No test results recorded yet.")
134
  print("Run tests first: python tests/run_tests.py")
135
  sys.exit(1)
136
 
 
122
  print()
123
 
124
 
125
+ def load_results() -> list[dict]:
126
+ """Load results from test_results.json, falling back to test_coverage.json."""
127
+ if RESULTS_FILE.exists():
128
+ try:
129
+ data = json.loads(RESULTS_FILE.read_text())
130
+ if data:
131
+ return data
132
+ except (json.JSONDecodeError, ValueError):
133
+ pass
134
 
135
+ # Fall back to the committed web coverage file
136
+ if WEB_COVERAGE_FILE.exists():
137
+ try:
138
+ coverage = json.loads(WEB_COVERAGE_FILE.read_text())
139
+ entries = coverage.get("matrix", [])
140
+ generated = coverage.get("generated_at", "2025-01-01T00:00:00+00:00")
141
+ return [
142
+ {
143
+ "timestamp": generated,
144
+ "os": e["os"],
145
+ "robot": e["robot"],
146
+ "suite": e["suite"],
147
+ "browser": e.get("browser"),
148
+ "passed": e.get("passed", 0),
149
+ "failed": e.get("failed", 0),
150
+ "errors": 0,
151
+ "total": e.get("total", 0),
152
+ "status": e.get("status", "pass"),
153
+ "returncode": 0,
154
+ }
155
+ for e in entries
156
+ ]
157
+ except (json.JSONDecodeError, ValueError):
158
+ pass
159
+
160
+ return []
161
+
162
+
163
+ def main() -> None:
164
+ results = load_results()
165
  if not results:
166
+ print("No test results found.")
167
  print("Run tests first: python tests/run_tests.py")
168
  sys.exit(1)
169