robotframework-events 0.2.0__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (28) hide show
  1. {robotframework_events-0.2.0/src/robotframework_events.egg-info → robotframework_events-0.4.0}/PKG-INFO +1 -1
  2. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/src/robotframework_events/__init__.py +1 -1
  3. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/src/robotframework_events/convert.py +2 -0
  4. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/src/robotframework_events/events-v1.schema.json +10 -2
  5. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/src/robotframework_events/events.py +2 -0
  6. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/src/robotframework_events/listener.py +19 -13
  7. {robotframework_events-0.2.0 → robotframework_events-0.4.0/src/robotframework_events.egg-info}/PKG-INFO +1 -1
  8. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/tests/test_events.py +12 -0
  9. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/LICENSE +0 -0
  10. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/README.md +0 -0
  11. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/pyproject.toml +0 -0
  12. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/setup.cfg +0 -0
  13. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/src/robotframework_events/__main__.py +0 -0
  14. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/src/robotframework_events/cli.py +0 -0
  15. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/src/robotframework_events/py.typed +0 -0
  16. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/src/robotframework_events/reader.py +0 -0
  17. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/src/robotframework_events/state.py +0 -0
  18. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/src/robotframework_events.egg-info/SOURCES.txt +0 -0
  19. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/src/robotframework_events.egg-info/dependency_links.txt +0 -0
  20. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/src/robotframework_events.egg-info/entry_points.txt +0 -0
  21. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/src/robotframework_events.egg-info/requires.txt +0 -0
  22. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/src/robotframework_events.egg-info/top_level.txt +0 -0
  23. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/tests/test_benchmark.py +0 -0
  24. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/tests/test_cli.py +0 -0
  25. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/tests/test_conformance.py +0 -0
  26. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/tests/test_model.py +0 -0
  27. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/tests/test_reader.py +0 -0
  28. {robotframework_events-0.2.0 → robotframework_events-0.4.0}/tests/test_state.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: robotframework-events
3
- Version: 0.2.0
3
+ Version: 0.4.0
4
4
  Summary: Robot Framework listener that writes execution events as JSON Lines
5
5
  Author: Tim de Groot
6
6
  License-Expression: MIT
@@ -27,4 +27,4 @@ __all__ = [
27
27
  "remove_callback",
28
28
  "schema",
29
29
  ]
30
- __version__ = "0.2.0"
30
+ __version__ = "0.4.0"
@@ -64,6 +64,7 @@ class _Converter:
64
64
  "run.started",
65
65
  self.t,
66
66
  run=run,
67
+ outputdir=os.path.dirname(os.path.abspath(path)),
67
68
  rf=match.group(1) if match else "unknown",
68
69
  python=match.group(2) if match else None,
69
70
  )
@@ -81,6 +82,7 @@ class _Converter:
81
82
  longname=suite.full_name,
82
83
  source=str(suite.source) if suite.source else None,
83
84
  tests=suite.test_count,
85
+ planned=[test.full_name for test in suite.all_tests] if parent is None else None,
84
86
  )
85
87
  counter = _Counter(id)
86
88
  if suite.has_setup:
@@ -51,7 +51,11 @@
51
51
  "rf": { "description": "Robot Framework version.", "type": "string" },
52
52
  "python": { "description": "Python version.", "type": "string" },
53
53
  "pid": { "type": "integer" },
54
- "cwd": { "type": "string" }
54
+ "cwd": { "type": "string" },
55
+ "outputdir": {
56
+ "description": "The run's output directory; log.html links screenshots and other files relative to it.",
57
+ "type": "string"
58
+ }
55
59
  }
56
60
  },
57
61
  "run.ended": {
@@ -70,7 +74,11 @@
70
74
  "name": { "type": "string" },
71
75
  "longname": { "type": "string" },
72
76
  "source": { "type": "string" },
73
- "tests": { "description": "Number of tests in the suite and its child suites.", "type": "integer", "minimum": 0 }
77
+ "tests": { "description": "Number of tests in the suite and its child suites.", "type": "integer", "minimum": 0 },
78
+ "planned": {
79
+ "description": "Top-level suite only: the full names of every test the run will execute, in run order.",
80
+ "$ref": "#/$defs/strings"
81
+ }
74
82
  }
75
83
  },
76
84
  "suite.ended": {
@@ -57,6 +57,7 @@ class RunStarted(Event):
57
57
  python: str | None = None
58
58
  pid: int | None = None
59
59
  cwd: str | None = None
60
+ outputdir: str | None = None
60
61
 
61
62
 
62
63
  @dataclass(slots=True, kw_only=True)
@@ -77,6 +78,7 @@ class SuiteStarted(Event):
77
78
  longname: str
78
79
  source: str | None = None
79
80
  tests: int
81
+ planned: list[str] | None = None
80
82
 
81
83
 
82
84
  @dataclass(slots=True, kw_only=True)
@@ -329,20 +329,21 @@ class Listener:
329
329
  with contextlib.suppress(OSError):
330
330
  self._out.flush()
331
331
 
332
- def _open_file(self) -> None:
332
+ def _output_locations(self) -> tuple[str, str | None]:
333
+ """${OUTPUT DIR} and ${OUTPUT FILE} of the run (cwd and None when they cannot be read)."""
334
+ from robot.libraries.BuiltIn import BuiltIn
335
+
336
+ try:
337
+ outdir = BuiltIn().get_variable_value("${OUTPUT DIR}") or os.getcwd()
338
+ output = BuiltIn().get_variable_value("${OUTPUT FILE}")
339
+ except Exception:
340
+ return os.getcwd(), None
341
+ return str(outdir), output
342
+
343
+ def _open_file(self, outdir: str, output: str | None) -> None:
333
344
  if self._file_option and self._file_option.upper() == "NONE":
334
345
  return
335
- if self._file_option:
336
- path = Path(self._file_option)
337
- else:
338
- from robot.libraries.BuiltIn import BuiltIn
339
-
340
- try:
341
- outdir = BuiltIn().get_variable_value("${OUTPUT DIR}") or os.getcwd()
342
- output = BuiltIn().get_variable_value("${OUTPUT FILE}")
343
- except Exception:
344
- outdir, output = os.getcwd(), None
345
- path = default_events_file(outdir, output)
346
+ path = Path(self._file_option) if self._file_option else default_events_file(outdir, output)
346
347
  try:
347
348
  path.parent.mkdir(parents=True, exist_ok=True)
348
349
  # buffered; flushed after every test and at close so tailing readers see progress
@@ -370,7 +371,8 @@ class Listener:
370
371
  if not self._started:
371
372
  self._started = True
372
373
  self._root = result
373
- self._open_file()
374
+ outdir, output = self._output_locations()
375
+ self._open_file(outdir, output)
374
376
  self._emit(
375
377
  "run.started",
376
378
  run=self._run_id,
@@ -378,6 +380,8 @@ class Listener:
378
380
  python=platform.python_version(),
379
381
  pid=os.getpid(),
380
382
  cwd=os.getcwd(),
383
+ # log.html links screenshots and other files relative to it
384
+ outputdir=outdir,
381
385
  )
382
386
  source = str(data.source) if data.source else None
383
387
  self._emit(
@@ -388,6 +392,8 @@ class Listener:
388
392
  longname=result.full_name,
389
393
  source=source,
390
394
  tests=data.test_count,
395
+ # the top-level suite lists every test the run will execute, for time estimates
396
+ planned=[test.full_name for test in data.all_tests] if not self._stack else None,
391
397
  )
392
398
  self._stack.append(_Frame(data.id, source, self._stack[-1] if self._stack else None))
393
399
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: robotframework-events
3
- Version: 0.2.0
3
+ Version: 0.4.0
4
4
  Summary: Robot Framework listener that writes execution events as JSON Lines
5
5
  Author: Tim de Groot
6
6
  License-Expression: MIT
@@ -22,9 +22,21 @@ def test_every_event_has_envelope_fields_and_gapless_seq(sample_events):
22
22
  assert all(e["v"] == 1 for e in sample_events)
23
23
 
24
24
 
25
+ def test_top_level_suite_lists_the_planned_tests(sample_events):
26
+ suites = by_type(sample_events, "suite.started")
27
+ assert suites[0]["planned"] == ["Sample.Passing With Structures", "Sample.Failing Test", "Sample.Skipped Test"]
28
+ assert all("planned" not in s for s in suites[1:])
29
+
30
+
31
+ def test_planned_tests_follow_the_selection(tmp_path: Path):
32
+ events, _ = run_with_listener(tmp_path, [DATA / "sample.robot"], test=["Failing Test"])
33
+ assert by_type(events, "suite.started")[0]["planned"] == ["Sample.Failing Test"]
34
+
35
+
25
36
  def test_run_events_frame_the_stream(sample_events):
26
37
  assert sample_events[0]["type"] == "run.started"
27
38
  assert sample_events[0]["run"]
39
+ assert sample_events[0]["outputdir"]
28
40
  assert sample_events[-1]["type"] == "run.ended"
29
41
  assert sample_events[-1]["stats"] == {"total": 3, "passed": 1, "failed": 1, "skipped": 1}
30
42