github-markup 4.0.2 → 5.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +4 -4
- data/.gitignore +3 -1
- data/Gemfile +2 -2
- data/HISTORY.md +10 -0
- data/github-markup.gemspec +5 -4
- data/lib/github/markup/command_implementation.rb +8 -28
- data/lib/github-markup.rb +1 -1
- data/test/markup_test.rb +6 -1
- data/test/markups/README.asciidoc.html +1 -1
- data/test/markups/README.hidetitle.asciidoc.html +1 -1
- data/test/markups/README.litcoffee.html +1 -1
- data/test/markups/README.long.rst +1319 -0
- data/test/markups/README.long.rst.html +1303 -0
- data/test/markups/README.mediawiki.html +9 -5
- data/test/markups/README.pod.html +8 -4
- data/test/markups/README.rst.html +4 -4
- data/test/markups/README.toc.asciidoc.html +1 -1
- data/test/markups/README.toc.rst.html +2 -2
- metadata +14 -10
@@ -0,0 +1,1319 @@
|
|
1
|
+
===================
|
2
|
+
Robot Framework 7.0
|
3
|
+
===================
|
4
|
+
|
5
|
+
.. default-role:: code
|
6
|
+
|
7
|
+
`Robot Framework`_ 7.0 is a new major release with highly enhanced listener interface
|
8
|
+
(`#3296`_), native `VAR` syntax for creating variables (`#3761`_), support for
|
9
|
+
mixing embedded and normal arguments with library keywords (`#4710`_), JSON
|
10
|
+
result format (`#4847`_) and various other enhancements and bug fixes.
|
11
|
+
|
12
|
+
Robot Framework 7.0 was released on Thursday January 11, 2024. Questions and comments
|
13
|
+
related to the release can be sent to the `#devel` channel on `Robot Framework Slack`_
|
14
|
+
and possible bugs submitted to the `issue tracker`_.
|
15
|
+
|
16
|
+
.. _Robot Framework: http://robotframework.org
|
17
|
+
.. _Robot Framework Foundation: http://robotframework.org/foundation
|
18
|
+
|
19
|
+
|
20
|
+
.. _pip: http://pip-installer.org
|
21
|
+
.. _PyPI: https://pypi.python.org/pypi/robotframework
|
22
|
+
.. _issue tracker milestone: https://github.com/robotframework/robotframework/milestone/64
|
23
|
+
.. _issue tracker: https://github.com/robotframework/robotframework/issues
|
24
|
+
.. _Slack: http://slack.robotframework.org
|
25
|
+
.. _Robot Framework Slack: Slack_
|
26
|
+
.. _installation instructions: ../../INSTALL.rst
|
27
|
+
|
28
|
+
.. contents::
|
29
|
+
:depth: 2
|
30
|
+
:local:
|
31
|
+
|
32
|
+
Installation
|
33
|
+
============
|
34
|
+
|
35
|
+
If you have pip_ installed, just run
|
36
|
+
|
37
|
+
::
|
38
|
+
|
39
|
+
pip install --upgrade robotframework
|
40
|
+
|
41
|
+
to install the latest available stable release or use
|
42
|
+
|
43
|
+
::
|
44
|
+
|
45
|
+
pip install robotframework==7.0
|
46
|
+
|
47
|
+
to install exactly this version. Alternatively you can download the package
|
48
|
+
from PyPI_ and install it manually. For more details and other installation
|
49
|
+
approaches, see the `installation instructions`_.
|
50
|
+
|
51
|
+
Most important enhancements
|
52
|
+
===========================
|
53
|
+
|
54
|
+
If you are interested to learn more about the new features in Robot Framework 7.0,
|
55
|
+
join the `RoboCon conference`__ in February, 2024. `Pekka Klärck`_, Robot Framework
|
56
|
+
lead developer, will go through the key features briefly in the `onsite conference`__
|
57
|
+
in Helsinki and more thoroughly in the `online edition`__.
|
58
|
+
|
59
|
+
The conference has also dozens of other great talks, workshops and a lot of
|
60
|
+
possibilities to meet other community members as well as developers of various
|
61
|
+
tools and libraries in the ecosystem. All profits from the conference will be
|
62
|
+
used for future Robot Framework development.
|
63
|
+
|
64
|
+
.. _Pekka Klärck: https://github.com/pekkaklarck
|
65
|
+
__ https://robocon.io
|
66
|
+
__ https://robocon.io/#live-opening-the-conference
|
67
|
+
__ https://robocon.io/#online-opening-the-conference-live
|
68
|
+
|
69
|
+
Listener enhancements
|
70
|
+
---------------------
|
71
|
+
|
72
|
+
Robot Framework's `listener interface`__ is a very powerful mechanism to get
|
73
|
+
notifications about various events during execution and it also allows modifying
|
74
|
+
data and results on the fly. It is not typically directly used by normal Robot
|
75
|
+
Framework users, but they are likely to use tools that use it internally.
|
76
|
+
The listener API has been significantly enhanced making it possible
|
77
|
+
to create even more powerful and interesting tools in the future.
|
78
|
+
|
79
|
+
__ http://robotframework.org/robotframework/latest/RobotFrameworkUserGuide.html#listener-interface
|
80
|
+
|
81
|
+
Support keywords and control structures with listener version 3
|
82
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
83
|
+
|
84
|
+
The major limitation with the listener API has been that the listener
|
85
|
+
API version 2 only supports getting notifications, not making modifications,
|
86
|
+
and that the more powerful listener API version 3 has only supported suites
|
87
|
+
and tests/tasks.
|
88
|
+
|
89
|
+
The biggest enhancement in the whole Robot Framework 7.0 is that the listener
|
90
|
+
version 3 has been extended to support also keywords and control structures (`#3296`_).
|
91
|
+
For example, a listener having the following methods prints information
|
92
|
+
about started keywords and ended WHILE loops:
|
93
|
+
|
94
|
+
.. code:: python
|
95
|
+
|
96
|
+
from robot import result, running
|
97
|
+
|
98
|
+
|
99
|
+
def start_keyword(data: running.Keyword, result: result.Keyword):
|
100
|
+
print(f"Keyword '{result.full_name}' used on line {data.lineno} started.")
|
101
|
+
|
102
|
+
|
103
|
+
def end_while(data: running.While, result: result.While):
|
104
|
+
print(f"WHILE loop on line {data.lineno} ended with status {result.status} "
|
105
|
+
f"after {len(result.body)} iterations.")
|
106
|
+
|
107
|
+
With keyword calls it is possible to also get more information about the actually
|
108
|
+
executed keyword. For example, the following listener prints some information
|
109
|
+
about the executed keyword and the library it belongs to:
|
110
|
+
|
111
|
+
.. code:: python
|
112
|
+
|
113
|
+
from robot.running import Keyword as KeywordData, LibraryKeyword
|
114
|
+
from robot.result import Keyword as KeywordResult
|
115
|
+
|
116
|
+
|
117
|
+
def start_library_keyword(data: KeywordData,
|
118
|
+
implementation: LibraryKeyword,
|
119
|
+
result: KeywordResult):
|
120
|
+
library = implementation.owner
|
121
|
+
print(f"Keyword '{implementation.name}' is implemented in library "
|
122
|
+
f"'{library.name}' at '{implementation.source}' on line "
|
123
|
+
f"{implementation.lineno}. The library has {library.scope.name} "
|
124
|
+
f"scope and the current instance is {library.instance}.")
|
125
|
+
|
126
|
+
As the above example already illustrated, it is even possible to get an access to
|
127
|
+
the actual library instance. This means that listeners can inspect the library
|
128
|
+
state and also modify it. With user keywords it is even possible to modify
|
129
|
+
the keyword itself or, via the `owner` resource file, any other keyword in
|
130
|
+
the resource file.
|
131
|
+
|
132
|
+
Listeners can also modify results if needed. Possible use cases include hiding
|
133
|
+
sensitive information and adding more details to results based on external sources.
|
134
|
+
|
135
|
+
Notice that although listener can change status of any executed keyword or control
|
136
|
+
structure, that does not directly affect the status of the executed test. In general
|
137
|
+
listeners cannot directly fail keywords so that execution would stop or handle
|
138
|
+
failures so that execution would continue. This kind of functionality may be
|
139
|
+
added in the future if there are needs.
|
140
|
+
|
141
|
+
The new listener version 3 methods are so powerful and versatile that going them
|
142
|
+
through thoroughly in these release notes is not possible. For more examples, you
|
143
|
+
can see the `acceptance tests`__ using the methods in various interesting and even
|
144
|
+
crazy ways.
|
145
|
+
|
146
|
+
__ https://github.com/robotframework/robotframework/tree/master/atest/testdata/output/listener_interface/body_items_v3
|
147
|
+
|
148
|
+
Listener version 3 is the default listener version
|
149
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
150
|
+
|
151
|
+
Earlier listeners always needed to specify the API version they used with the
|
152
|
+
`ROBOT_LISTENER_API_VERSION` attribute. Now that the listener version 3 got
|
153
|
+
the new methods, it is considered so much more powerful than the version 2
|
154
|
+
that it was made the default listener version (`#4910`_).
|
155
|
+
|
156
|
+
The listener version 2 continues to work, but using it requires specifying
|
157
|
+
the listener version as earlier. The are no plans to deprecate the listener
|
158
|
+
version 2, but we nevertheless highly recommend using the version 3 whenever
|
159
|
+
possible.
|
160
|
+
|
161
|
+
Libraries can register themselves as listeners by using string `SELF`
|
162
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
163
|
+
|
164
|
+
Listeners are typically enabled from the command line, but libraries
|
165
|
+
can register listeners as well. Often libraries themselves want to act
|
166
|
+
as listeners, and that has earlier required using `self.ROBOT_LIBRARY_LISTENER = self`
|
167
|
+
in the `__init__` method. Robot Framework 7.0 makes it possible to use string
|
168
|
+
`SELF` (case-insensitive) for this purpose as well (`#4910`_), which means
|
169
|
+
that a listener can be specified as a class attribute and not only in `__init__`.
|
170
|
+
This is especially convenient when using the `@library` decorator:
|
171
|
+
|
172
|
+
.. code:: python
|
173
|
+
|
174
|
+
from robot.api.deco import keyword, library
|
175
|
+
|
176
|
+
|
177
|
+
@library(listener='SELF')
|
178
|
+
class Example:
|
179
|
+
|
180
|
+
def start_suite(self, data, result):
|
181
|
+
...
|
182
|
+
|
183
|
+
@keyword
|
184
|
+
def example(self, arg):
|
185
|
+
...
|
186
|
+
|
187
|
+
Nicer API for modifying keyword arguments
|
188
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
189
|
+
|
190
|
+
Modifying keyword call arguments programmatically has been made more convenient
|
191
|
+
(`#5000`_). This enhancement eases modifying arguments using the new listener
|
192
|
+
version 3 `start/end_keyword` methods.
|
193
|
+
|
194
|
+
Paths are passed to version 3 listeners as `pathlib.Path` objects
|
195
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
196
|
+
|
197
|
+
Listeners have methods like `output_file` and `log_file` that are called when
|
198
|
+
result files are ready so that they get the file path as an argument. Earlier
|
199
|
+
paths were strings, but nowadays listener version 3 methods get them as
|
200
|
+
more convenient `pathlib.Path`__ objects.
|
201
|
+
|
202
|
+
__ https://docs.python.org/3/library/pathlib.html
|
203
|
+
|
204
|
+
Native `VAR` syntax
|
205
|
+
-------------------
|
206
|
+
|
207
|
+
The new `VAR` syntax (`#3761`_) makes it possible to create local variables
|
208
|
+
as well as global, suite and test/task scoped variables dynamically during
|
209
|
+
execution. The motivation is to have a more convenient syntax than using
|
210
|
+
the `Set Variable` keyword for creating local variables and to unify
|
211
|
+
the syntax for creating variables in different scopes. Except for the mandatory
|
212
|
+
`VAR` marker, the syntax is also the same as when creating variables in the
|
213
|
+
Variables section. The syntax is best explained with examples:
|
214
|
+
|
215
|
+
.. code:: robotframework
|
216
|
+
|
217
|
+
*** Test Cases ***
|
218
|
+
Example
|
219
|
+
# Create a local variable `${local}` with a value `value`.
|
220
|
+
VAR ${local} value
|
221
|
+
|
222
|
+
# Create a variable that is available throughout the whole suite.
|
223
|
+
# Supported scopes are GLOBAL, SUITE, TEST, TASK and LOCAL (default).
|
224
|
+
VAR ${suite} value scope=SUITE
|
225
|
+
|
226
|
+
# Validate created variables.
|
227
|
+
Should Be Equal ${local} value
|
228
|
+
Should Be Equal ${suite} value
|
229
|
+
|
230
|
+
Example continued
|
231
|
+
# Suite level variables are seen also by subsequent tests.
|
232
|
+
Should Be Equal ${suite} value
|
233
|
+
|
234
|
+
When creating `${scalar}` variables having long values, it is possible to split
|
235
|
+
the value to multiple lines. Lines are joined together with a space by default,
|
236
|
+
but that can be changed with the `separator` configuration option. Similarly as
|
237
|
+
in the Variables section, it is possible to create also `@{list}` and `&{dict}`
|
238
|
+
variables. Unlike in the Variables section, variables can be created conditionally
|
239
|
+
using IF/ELSE structures:
|
240
|
+
|
241
|
+
.. code:: robotframework
|
242
|
+
|
243
|
+
*** Test Cases ***
|
244
|
+
Long value
|
245
|
+
VAR ${long}
|
246
|
+
... This value is rather long.
|
247
|
+
... It has been split to multiple lines.
|
248
|
+
... Parts will be joined together with a space.
|
249
|
+
|
250
|
+
Multiline
|
251
|
+
VAR ${multiline}
|
252
|
+
... First line.
|
253
|
+
... Second line.
|
254
|
+
... Last line.
|
255
|
+
... separator=\n
|
256
|
+
|
257
|
+
List
|
258
|
+
# Creates a list with three items.
|
259
|
+
VAR @{list} a b c
|
260
|
+
|
261
|
+
Dictionary
|
262
|
+
# Creates a dictionary with two items.
|
263
|
+
VAR &{dict} key=value second=item
|
264
|
+
|
265
|
+
Normal IF
|
266
|
+
IF 1 > 0
|
267
|
+
VAR ${x} true value
|
268
|
+
ELSE
|
269
|
+
VAR ${x} false value
|
270
|
+
END
|
271
|
+
|
272
|
+
Inline IF
|
273
|
+
IF 1 > 0 VAR ${x} true value ELSE VAR ${x} false value
|
274
|
+
|
275
|
+
Mixed argument support with library keywords
|
276
|
+
--------------------------------------------
|
277
|
+
|
278
|
+
User keywords got support to use both embedded and normal arguments in Robot
|
279
|
+
Framework 6.1 (`#4234`__) and now that support has been added also to library keywords
|
280
|
+
(`#4710`_). The syntax works so, that if a function or method implementing a keyword
|
281
|
+
accepts more arguments than there are embedded arguments, the remaining arguments
|
282
|
+
can be passed in as normal arguments. This is illustrated by the following example
|
283
|
+
keyword:
|
284
|
+
|
285
|
+
.. code:: python
|
286
|
+
|
287
|
+
@keyword('Number of ${animals} should be')
|
288
|
+
def example(animals, count):
|
289
|
+
...
|
290
|
+
|
291
|
+
The above keyword could be used like this:
|
292
|
+
|
293
|
+
.. code:: robotframework
|
294
|
+
|
295
|
+
*** Test Cases ***
|
296
|
+
Example
|
297
|
+
Number of horses should be 2
|
298
|
+
Number of horses should be count=2
|
299
|
+
Number of dogs should be 3
|
300
|
+
|
301
|
+
__ https://github.com/robotframework/robotframework/issues/4234
|
302
|
+
|
303
|
+
JSON result format
|
304
|
+
------------------
|
305
|
+
|
306
|
+
Robot Framework 6.1 added support to `convert test/task data to JSON and back`__
|
307
|
+
and Robot Framework 7.0 extends the JSON serialization support to execution results
|
308
|
+
(`#4847`_). One of the core use cases for data serialization was making it easy to
|
309
|
+
transfer data between process and machines, and now it is also easy to pass results
|
310
|
+
back.
|
311
|
+
|
312
|
+
Also the built-in Rebot tool that is used for post-processing results supports
|
313
|
+
JSON files both in output and in input. Creating JSON output files is done using
|
314
|
+
the normal `--output` option so that the specified file has a `.json` extension::
|
315
|
+
|
316
|
+
rebot --output output.json output.xml
|
317
|
+
|
318
|
+
When reading output files, JSON files are automatically recognized by
|
319
|
+
the extension::
|
320
|
+
|
321
|
+
rebot output.json
|
322
|
+
rebot output1.json output2.json
|
323
|
+
|
324
|
+
When combining or merging results, it is possible to mix JSON and XML files::
|
325
|
+
|
326
|
+
rebot output1.xml output2.json
|
327
|
+
rebot --merge original.xml rerun.json
|
328
|
+
|
329
|
+
The JSON output file structure is documented in the `result.json` `schema file`__.
|
330
|
+
|
331
|
+
The plan is to enhance the support for JSON output files in the future so that
|
332
|
+
they could be created already during execution. For more details see issue `#3423`__.
|
333
|
+
|
334
|
+
__ https://github.com/robotframework/robotframework/blob/master/doc/releasenotes/rf-6.1.rst#json-data-format
|
335
|
+
__ https://github.com/robotframework/robotframework/tree/master/doc/schema#readme
|
336
|
+
__ https://github.com/robotframework/robotframework/issues/3423
|
337
|
+
|
338
|
+
Argument conversion enhancements
|
339
|
+
--------------------------------
|
340
|
+
|
341
|
+
Automatic argument conversion is a very powerful feature that library developers
|
342
|
+
can use to avoid converting arguments manually and to get more useful Libdoc
|
343
|
+
documentation. There are two important new enhancements to it.
|
344
|
+
|
345
|
+
Support for `Literal`
|
346
|
+
~~~~~~~~~~~~~~~~~~~~~
|
347
|
+
|
348
|
+
In Python, the Literal__ type makes it possible to type arguments so that type
|
349
|
+
checkers accept only certain values. For example, this function only accepts
|
350
|
+
strings `x`, `y` and `z`:
|
351
|
+
|
352
|
+
.. code:: python
|
353
|
+
|
354
|
+
def example(arg: Literal['x', 'y', 'z']):
|
355
|
+
...
|
356
|
+
|
357
|
+
Robot Framework has been enhanced so that it validates that an argument having
|
358
|
+
a `Literal` type can only be used with the specified values (`#4633`_). For
|
359
|
+
example, using a keyword with the above implementation with a value `xxx` would
|
360
|
+
fail.
|
361
|
+
|
362
|
+
In addition to validation, arguments are also converted. For example, if an
|
363
|
+
argument accepts `Literal[-1, 0, 1]`, used arguments are converted to
|
364
|
+
integers and then validated. In addition to that, string matching is case, space,
|
365
|
+
underscore and hyphen insensitive. In all cases exact matches have a precedence
|
366
|
+
and the argument that is passed to the keyword is guaranteed to be in the exact
|
367
|
+
format used with `Literal`.
|
368
|
+
|
369
|
+
`Literal` conversion is in many ways similar to Enum__ conversion that Robot
|
370
|
+
Framework has supported for long time. `Enum` conversion has benefits like
|
371
|
+
being able to use a custom documentation and it is typically better when using
|
372
|
+
the same type multiple times. In simple cases being able to just use
|
373
|
+
`arg: Literal[...]` without defining a new type is very convenient, though.
|
374
|
+
|
375
|
+
__ https://docs.python.org/3/library/typing.html#typing.Literal
|
376
|
+
__ https://docs.python.org/3/library/enum.html
|
377
|
+
|
378
|
+
Support "stringified" types like `'list[int]'` and `'int | float'`
|
379
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
380
|
+
|
381
|
+
Python's type hinting syntax has evolved so that generic types can be parameterized
|
382
|
+
like `list[int]` (new in `Python 3.9`__) and unions written as `int | float`
|
383
|
+
(new in `Python 3.10`__). Using these constructs with older Python versions causes
|
384
|
+
errors, but Python type checkers support also "stringified" type hints like
|
385
|
+
`'list[int]'` and `'int | float'` that work regardless the Python version.
|
386
|
+
|
387
|
+
Support for stringified generics and unions has now been added also to
|
388
|
+
Robot Framework's argument conversion (`#4711`_). For example,
|
389
|
+
the following typing now also works with Python 3.8:
|
390
|
+
|
391
|
+
.. code:: python
|
392
|
+
|
393
|
+
def example(a: 'list[int]', b: 'int | float'):
|
394
|
+
...
|
395
|
+
|
396
|
+
These stringified types are also compatible with the Remote library API and other
|
397
|
+
scenarios where using actual types is not possible.
|
398
|
+
|
399
|
+
__ https://peps.python.org/pep-0585
|
400
|
+
__ https://peps.python.org/pep-0604
|
401
|
+
|
402
|
+
Tags set globally can be removed using `-tag` syntax
|
403
|
+
----------------------------------------------------
|
404
|
+
|
405
|
+
Individual tests and keywords can nowadays remove tags that have been set in
|
406
|
+
the Settings section with `Test Tags` or `Keyword Tags` settings by using
|
407
|
+
the `-tag` syntax with their own `[Tags]` setting (`#4374`_). For example,
|
408
|
+
tests `T1` and `T3` below get tags `all` and `most`, and test `T2` gets
|
409
|
+
tags `all` and `one`:
|
410
|
+
|
411
|
+
.. code:: robotframework
|
412
|
+
|
413
|
+
*** Settings ***
|
414
|
+
Test Tags all most
|
415
|
+
|
416
|
+
*** Test Cases ***
|
417
|
+
T1
|
418
|
+
No Operation
|
419
|
+
T2
|
420
|
+
[Tags] one -most
|
421
|
+
No Operation
|
422
|
+
T3
|
423
|
+
No Operation
|
424
|
+
|
425
|
+
With tests it is possible to get the same effect by using the `Default Tags`
|
426
|
+
setting and overriding it where needed. That syntax is, however, considered
|
427
|
+
deprecated (`#4365`__) and using the new `-tag` syntax is recommended. With
|
428
|
+
keywords there was no similar functionality earlier.
|
429
|
+
|
430
|
+
__ https://github.com/robotframework/robotframework/issues/4365
|
431
|
+
|
432
|
+
Dynamic and hybrid library APIs support asynchronous execution
|
433
|
+
--------------------------------------------------------------
|
434
|
+
|
435
|
+
Dynamic and hybrid libraries nowadays support asynchronous execution.
|
436
|
+
In practice the special methods like `get_keyword_names` and `run_keyword`
|
437
|
+
can be implemented as async methods (`#4803`_).
|
438
|
+
|
439
|
+
Async support was added to the normal static library API in Robot Framework
|
440
|
+
6.1 (`#4089`_). A bug related to handling asynchronous keywords if execution
|
441
|
+
is stopped gracefully has also been fixed (`#4808`_).
|
442
|
+
|
443
|
+
.. _#4089: https://github.com/robotframework/robotframework/issues/4089
|
444
|
+
|
445
|
+
Timestamps in result model and output.xml use standard format
|
446
|
+
-------------------------------------------------------------
|
447
|
+
|
448
|
+
Timestamps used in the result model and stored to the output.xml file used custom
|
449
|
+
format like `20231107 19:57:01.123` earlier. Non-standard formats are seldom
|
450
|
+
a good idea, and in this case parsing the custom format turned out to be slow
|
451
|
+
as well.
|
452
|
+
|
453
|
+
Nowadays the result model stores timestamps as standard datetime_ objects and
|
454
|
+
elapsed times as a timedelta_ (`#4258`_). This makes creating timestamps and
|
455
|
+
operating with them more convenient and considerably faster. The new objects can
|
456
|
+
be accessed via `start_time`, `end_time` and `elapsed_time` attributes that were
|
457
|
+
added as forward compatibility already in Robot Framework 6.1 (`#4765`_).
|
458
|
+
Old information is still available via the old `starttime`, `endtime` and
|
459
|
+
`elapsedtime` attributes, so this change is fully backwards compatible.
|
460
|
+
|
461
|
+
The timestamp format in output.xml has also been changed from the custom
|
462
|
+
`YYYYMMDD HH:MM:SS.mmm` format to `ISO 8601`_ compatible
|
463
|
+
`YYYY-MM-DDTHH:MM:SS.mmmmmm`. Using a standard format makes it
|
464
|
+
easier to process output.xml files, but this change also has big positive
|
465
|
+
performance effect. Now that the result model stores timestamps as datetime_
|
466
|
+
objects, formatting and parsing them with the available `isoformat()`__ and
|
467
|
+
`fromisoformat()`__ methods is very fast compared to custom formatting and parsing.
|
468
|
+
|
469
|
+
A related change is that instead of storing start and end times of each executed
|
470
|
+
item in output.xml, we nowadays store their start and elapsed times. Elapsed times
|
471
|
+
are represented as floats denoting seconds. Having elapsed times directly available
|
472
|
+
is a lot more convenient than calculating them based on start and end times.
|
473
|
+
Storing start and elapsed times also takes less space than storing start and end times.
|
474
|
+
|
475
|
+
As the result of these changes, times are available in the result model and in
|
476
|
+
output.xml in higher precision than earlier. Earlier times were stored in millisecond
|
477
|
+
granularity, but nowadays they use microseconds. Logs and reports still use milliseconds,
|
478
|
+
but that can be changed in the future if there are needs.
|
479
|
+
|
480
|
+
Changes to output.xml are backwards incompatible and affect all external tools
|
481
|
+
that process timestamps. This is discussed more in `Changes to output.xml`_
|
482
|
+
section below along with other output.xml changes.
|
483
|
+
|
484
|
+
.. _datetime: https://docs.python.org/3/library/datetime.html#datetime-objects
|
485
|
+
.. _timedelta: https://docs.python.org/3/library/datetime.html#timedelta-objects
|
486
|
+
.. _#4765: https://github.com/robotframework/robotframework/issues/4765
|
487
|
+
.. _ISO 8601: https://en.wikipedia.org/wiki/ISO_8601
|
488
|
+
__ https://docs.python.org/3/library/datetime.html#datetime.datetime.isoformat
|
489
|
+
__ https://docs.python.org/3/library/datetime.html#datetime.datetime.fromisoformat
|
490
|
+
|
491
|
+
Dark mode support to report and log
|
492
|
+
-----------------------------------
|
493
|
+
|
494
|
+
Report and log got a new dark mode (`#3725`_). It is enabled automatically based
|
495
|
+
on browser and operating system preferences, but there is also a toggle to
|
496
|
+
switch between the modes.
|
497
|
+
|
498
|
+
Backwards incompatible changes
|
499
|
+
==============================
|
500
|
+
|
501
|
+
Python 3.6 and 3.7 are no longer supported
|
502
|
+
------------------------------------------
|
503
|
+
|
504
|
+
Robot Framework 7.0 requires Python 3.8 or newer (`#4294`_). The last version
|
505
|
+
that supports Python 3.6 and 3.7 is Robot Framework 6.1.1.
|
506
|
+
|
507
|
+
Changes to output.xml
|
508
|
+
---------------------
|
509
|
+
|
510
|
+
The output.xml file has changed in different ways making Robot Framework 7.0
|
511
|
+
incompatible with external tools processing output.xml files until these tools
|
512
|
+
are updated. We try to avoid this kind of breaking changes, but in this case
|
513
|
+
especially the changes to timestamps were considered so important that we
|
514
|
+
eventually would have needed to do them anyway.
|
515
|
+
|
516
|
+
Due to the changes being relatively big, it can take some time before external
|
517
|
+
tools are updated. To allow users to take Robot Framework 7.0 into use also
|
518
|
+
if they depend on an incompatible tool, it is possible to use the new
|
519
|
+
`--legacy-output` option both as part of execution and with the Rebot tool
|
520
|
+
to generate output.xml files that are compatible with older versions.
|
521
|
+
|
522
|
+
Timestamp related changes
|
523
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~
|
524
|
+
|
525
|
+
The biggest changes in output.xml are related to timestamps (`#4258`_).
|
526
|
+
With earlier versions start and end times of executed items, as well as timestamps
|
527
|
+
of the logged messages, were stored using a custom `YYYYMMDD HH:MM:SS.mmm` format,
|
528
|
+
but nowadays the format is `ISO 8601`_ compatible `YYYY-MM-DDTHH:MM:SS.mmmmmm`.
|
529
|
+
In addition to that, instead of saving start and end times to `starttime` and
|
530
|
+
`endtime` attributes and message times to `timestamp`, start and elapsed times
|
531
|
+
are now stored to `start` and `elapsed` attributes and message times to `time`.
|
532
|
+
|
533
|
+
Examples:
|
534
|
+
|
535
|
+
.. code:: xml
|
536
|
+
|
537
|
+
<!-- Old format -->
|
538
|
+
<msg timestamp="20231108 15:36:34.278" level="INFO">Hello world!</msg>
|
539
|
+
<status status="PASS" starttime="20231108 15:37:35.046" endtime="20231108 15:37:35.046"/>
|
540
|
+
|
541
|
+
<!-- New format -->
|
542
|
+
<msg time="2023-11-08T15:36:34.278343" level="INFO">Hello world!</msg>
|
543
|
+
<status status="PASS" start="2023-11-08T15:37:35.046153" elapsed="0.000161"/>
|
544
|
+
|
545
|
+
The new format is standard compliant, contains more detailed times, makes the elapsed
|
546
|
+
time directly available and makes the `<status>` elements over 10% shorter.
|
547
|
+
These are all great benefits, but we are still sorry for all the extra work
|
548
|
+
this causes for those developing tools that process output.xml files.
|
549
|
+
|
550
|
+
Keyword name related changes
|
551
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
552
|
+
|
553
|
+
How keyword names are stored in output.xml has changed slightly (`#4884`_).
|
554
|
+
With each executed keywords we store both the name of the keyword and the name
|
555
|
+
of the library or resource file containing it. Earlier the latter was stored to
|
556
|
+
attribute `library` also with resource files, but nowadays the attribute is generic
|
557
|
+
`owner`. In addition to `owner` being a better name in general, it also
|
558
|
+
matches the new `owner` attribute keywords in the result model have.
|
559
|
+
|
560
|
+
Another change is that the original name stored with keywords using embedded
|
561
|
+
arguments is nowadays in `source_name` attribute when it used to be in `sourcename`.
|
562
|
+
This change was done to make the attribute consistent with the attribute in
|
563
|
+
the result model.
|
564
|
+
|
565
|
+
Examples:
|
566
|
+
|
567
|
+
.. code:: xml
|
568
|
+
|
569
|
+
<!-- Old format -->
|
570
|
+
<kw name="Log" library="BuiltIn">...</kw>
|
571
|
+
<kw name="Number of horses should be" sourcename="Number of ${animals} should be" library="my_resource">...</kw>
|
572
|
+
|
573
|
+
<!-- New format -->
|
574
|
+
<kw name="Log" owner="BuiltIn">...</kw>
|
575
|
+
<kw name="Number of horses should be" source_name="Number of ${animals} should be" owner="my_resource">...</kw>
|
576
|
+
|
577
|
+
Other changes
|
578
|
+
~~~~~~~~~~~~~
|
579
|
+
|
580
|
+
Nowadays keywords and control structures can have a message. Messages are represented
|
581
|
+
as the text of the `<status>` element, and they have been present already earlier with
|
582
|
+
tests and suites. Related to this, control structured cannot anymore have `<doc>`.
|
583
|
+
(`#4883`_)
|
584
|
+
|
585
|
+
These changes should not cause problems for tools processing output.xml files,
|
586
|
+
but storing messages with each failed keyword and control structure may
|
587
|
+
increase the output.xml size.
|
588
|
+
|
589
|
+
Schema updates
|
590
|
+
~~~~~~~~~~~~~~
|
591
|
+
|
592
|
+
The output.xml schema has been updated and can be found via
|
593
|
+
https://github.com/robotframework/robotframework/tree/master/doc/schema/.
|
594
|
+
|
595
|
+
Changes to result model
|
596
|
+
-----------------------
|
597
|
+
|
598
|
+
There have been some changes to the result model that unfortunately affect
|
599
|
+
external tools using it. The main motivation for these changes has been
|
600
|
+
cleaning up the model before creating a JSON representation for it (`#4847`_).
|
601
|
+
|
602
|
+
Changes related to keyword names
|
603
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
604
|
+
|
605
|
+
The biggest changes are related to keyword names (`#4884`_). Earlier `Keyword`
|
606
|
+
objects had a `name` attribute that contained the full keyword name like
|
607
|
+
`BuiltIn.Log`. The actual keyword name and the name of the library or resource
|
608
|
+
file that the keyword belonged to were in `kwname` and `libname` attributes,
|
609
|
+
respectively. In addition to these, keywords using embedded arguments also had
|
610
|
+
a `sourcename` attribute containing the original keyword name.
|
611
|
+
|
612
|
+
Due to reasons explained in `#4884`_, the following changes have been made
|
613
|
+
in Robot Framework 7.0:
|
614
|
+
|
615
|
+
- Old `kwname` is renamed to `name`. This is consistent with the execution side `Keyword`.
|
616
|
+
- Old `libname` is renamed to generic `owner`.
|
617
|
+
- New `full_name` is introduced to replace the old `name`.
|
618
|
+
- `sourcename` is renamed to `source_name`.
|
619
|
+
- `kwname`, `libname` and `sourcename` are preserved as properties. They are considered
|
620
|
+
deprecated, but accessing them does not cause a deprecation warning yet.
|
621
|
+
|
622
|
+
The backwards incompatible part of this change is changing the meaning of the
|
623
|
+
`name` attribute. It used to be a read-only property yielding the full name
|
624
|
+
like `BuiltIn.Log`, but now it is a normal attribute that contains just the actual
|
625
|
+
keyword name like `Log`. All other old attributes have been preserved as properties
|
626
|
+
and code using them does not need to be updated immediately.
|
627
|
+
|
628
|
+
Deprecated attributes have been removed
|
629
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
630
|
+
|
631
|
+
The following attributes that were deprecated already in Robot Framework 4.0
|
632
|
+
have been removed (`#4846`_):
|
633
|
+
|
634
|
+
- `TestSuite.keywords`. Use `TestSuite.setup` and `TestSuite.teardown` instead.
|
635
|
+
- `TestCase.keywords`. Use `TestCase.body`, `TestCase.setup` and `TestCase.teardown` instead.
|
636
|
+
- `Keyword.keywords`. Use `Keyword.body` and `Keyword.teardown` instead.
|
637
|
+
- `Keyword.children`. Use `Keyword.body` and `Keyword.teardown` instead.
|
638
|
+
- `TestCase.critical`. The whole criticality concept has been removed.
|
639
|
+
|
640
|
+
Additionally, `TestSuite.keywords` and `TestCase.keywords` have been removed
|
641
|
+
from the execution model.
|
642
|
+
|
643
|
+
Changes to parsing model
|
644
|
+
------------------------
|
645
|
+
|
646
|
+
There have been some changes also to the parsing model:
|
647
|
+
|
648
|
+
- The node representing the deprecated `[Return]` setting has been renamed from
|
649
|
+
`Return` to `ReturnSetting`. At the same time, the node representing the
|
650
|
+
`RETURN` statement has been renamed from `ReturnStatement` to `Return` (`#4939`_).
|
651
|
+
|
652
|
+
To ease transition, `ReturnSetting` has existed as an alias for `Return` starting
|
653
|
+
from Robot Framework 6.1 (`#4656`_) and `ReturnStatement` is preserved as an alias
|
654
|
+
now. In addition to that, the `ModelVisitor` base class has special handling for
|
655
|
+
`visit_ReturnSetting` and `visit_ReturnStatement` visitor methods so that they work
|
656
|
+
correctly with `ReturnSetting` and `ReturnStatement` with Robot Framework 6.1 and
|
657
|
+
newer. Issue `#4939`_ explains this in more detail and has a concrete example
|
658
|
+
how to support also older Robot Framework versions.
|
659
|
+
|
660
|
+
- The node representing the `Test Tags` setting as well as the deprecated
|
661
|
+
`Force Tags` setting has been renamed from `ForceTags` to `TestTags` (`#4385`_).
|
662
|
+
`ModelVisitor` has special handling for the `visit_ForceTags` method so
|
663
|
+
that it will continue to work also after the change.
|
664
|
+
|
665
|
+
- The token type used with `AS` (or `WITH NAME`) in library imports has been changed
|
666
|
+
to `Token.AS` (`#4375`_). `Token.WITH_NAME` still exists as an alias for `Token.AS`.
|
667
|
+
|
668
|
+
- Statement `type` and `tokens` have been moved from `_fields` to `_attributes` (`#4912`_).
|
669
|
+
This may affect debugging the model.
|
670
|
+
|
671
|
+
.. _#4656: https://github.com/robotframework/robotframework/issues/4656
|
672
|
+
|
673
|
+
Changes to Libdoc spec files
|
674
|
+
----------------------------
|
675
|
+
|
676
|
+
The following deprecated constructs have been removed from Libdoc spec files (`#4667`_):
|
677
|
+
|
678
|
+
- `datatypes` have been removed from XML or JSON spec files. They were deprecated in
|
679
|
+
favor of `typedocs` already in Robot Framework 5.0 (`#4160`_).
|
680
|
+
- Type names are not anymore written to XML specs as content of the `<type>` elements.
|
681
|
+
The name is available as the `name` attribute of `<type>` elements since
|
682
|
+
Robot Framework 6.1 (`#4538`_).
|
683
|
+
- `types` and `typedocs` attributes have been removed from arguments in JSON specs.
|
684
|
+
The `type` attribute introduced in RF 6.1 (`#4538`_) needs to be used instead.
|
685
|
+
|
686
|
+
Libdoc schema files have been updated and can be found via
|
687
|
+
https://github.com/robotframework/robotframework/tree/master/doc/schema/.
|
688
|
+
|
689
|
+
.. _#4160: https://github.com/robotframework/robotframework/issues/4160
|
690
|
+
.. _#4538: https://github.com/robotframework/robotframework/issues/4538
|
691
|
+
|
692
|
+
Changes to selecting tests with `--suite`, `--test` and `--include`
|
693
|
+
-------------------------------------------------------------------
|
694
|
+
|
695
|
+
There are two changes related to selecting tests:
|
696
|
+
|
697
|
+
- When using `--test` and `--include` together, tests matching either of them
|
698
|
+
are selected (`#4721`_). Earlier tests need to match both options to be selected.
|
699
|
+
|
700
|
+
- When selecting a suite using its parent suite as a prefix like `--suite parent.suite`,
|
701
|
+
the given name must match the full suite name (`#4720`_). Earlier it was enough if
|
702
|
+
the prefix matched the closest parent or parents.
|
703
|
+
|
704
|
+
Other backwards incompatible changes
|
705
|
+
------------------------------------
|
706
|
+
|
707
|
+
- The default value of the `stdin` argument used with `Process` library keyword
|
708
|
+
has been changed from `subprocess.PIPE` to `None` (`#4103`_). This change ought
|
709
|
+
to avoid processes hanging in some cases. Those who depend on the old behavior
|
710
|
+
need to use `stdin=PIPE` explicitly to enable that.
|
711
|
+
|
712
|
+
- When type hints are specified as strings, they must use format `type`, `type[param]`,
|
713
|
+
`type[p1, p2]` or `t1 | t2` (`#4711`_). Using other formats will cause errors taking
|
714
|
+
keywords into use. In practice problems occur if the special characters `[`, `]`, `,`
|
715
|
+
and `|` occur in unexpected places. For example, `arg: "Hello, world!"` will cause
|
716
|
+
an error due to the comma.
|
717
|
+
|
718
|
+
- `datetime`, `date` and `timedelta` objects are sent over the Remote interface
|
719
|
+
differently than earlier (`#4784`_). They all used to be converted to strings, but
|
720
|
+
nowadays `datetime` is sent as-is, `date` is converted to `datetime` and sent like
|
721
|
+
that, and `timedelta` is converted to a `float` by using `timedelta.total_seconds()`.
|
722
|
+
|
723
|
+
- Argument conversion support with `collections.abc.ByteString` has been removed (`#4983`_).
|
724
|
+
The reason is that `ByteString` is deprecated and will be removed in Python 3.14.
|
725
|
+
It has not been too often needed, but if you happen to use it, you can change
|
726
|
+
`arg: ByteString` to `arg: bytes | bytearray` and the functionality
|
727
|
+
stays exactly the same.
|
728
|
+
|
729
|
+
- Paths passed to result file related listener version 3 methods like `output_file`
|
730
|
+
and `log_file` have been changed from strings to `pathlib.Path` objects (`#4988`_).
|
731
|
+
Most of the time both kinds of paths work interchangeably, so this change is unlikely
|
732
|
+
to cause issues. If you need to handle these paths as strings, they can be converted
|
733
|
+
by using `str(path)`.
|
734
|
+
|
735
|
+
- `robot.utils.normalize` does not anymore support bytes (`#4936`_).
|
736
|
+
|
737
|
+
- Deprecated `accept_plain_values` argument has been removed from the
|
738
|
+
`timestr_to_secs` utility function (`#4861`_).
|
739
|
+
|
740
|
+
Deprecations
|
741
|
+
============
|
742
|
+
|
743
|
+
`[Return]` setting
|
744
|
+
------------------
|
745
|
+
|
746
|
+
The `[Return]` setting for specifying the return value from user keywords has
|
747
|
+
been "loudly" deprecated (`#4876`_). It has been "silently" deprecated since
|
748
|
+
Robot Framework 5.0 when the much more versatile `RETURN` setting was introduced
|
749
|
+
(`#4078`_), but now using it will cause a deprecation warning. The plan is to
|
750
|
+
preserve the `[Return]` setting at least until Robot Framework 8.0.
|
751
|
+
|
752
|
+
If you have lot of data that uses `[Return]`, the easiest way to update it is
|
753
|
+
using the Robotidy_ tool that can convert `[Return]` to `RETURN` automatically.
|
754
|
+
If you have data that is executed also with Robot Framework versions that do
|
755
|
+
not support `RETURN`, you can use the `Return From Keyword` keyword instead.
|
756
|
+
That keyword will eventually be deprecated and removed as well, though.
|
757
|
+
|
758
|
+
.. _#4078: https://github.com/robotframework/robotframework/issues/4078
|
759
|
+
.. _Robotidy: https://robotidy.readthedocs.io
|
760
|
+
|
761
|
+
Singular section headers
|
762
|
+
------------------------
|
763
|
+
|
764
|
+
Using singular section headers like `*** Test Case ***` or `*** Setting ***`
|
765
|
+
nowadays causes a deprecation warning (`#4432`_). They were silently deprecated
|
766
|
+
in Robot Framework 6.0 for reasons explained in issue `#4431`_.
|
767
|
+
|
768
|
+
.. _#4431: https://github.com/robotframework/robotframework/issues/4431
|
769
|
+
|
770
|
+
Deprecated attributes in parsing, running and result models
|
771
|
+
-----------------------------------------------------------
|
772
|
+
|
773
|
+
- In the parsing model, `For.variables`, `ForHeader.variables`, `Try.variable` and
|
774
|
+
`ExceptHeader.variable` attributes have been deprecated in favor of the new `assign`
|
775
|
+
attribute (`#4708`_).
|
776
|
+
|
777
|
+
- In running and result models, `For.variables` and `TryBranch.variable` have been
|
778
|
+
deprecated in favor of the new `assign` attribute (`#4708`_).
|
779
|
+
|
780
|
+
- In the result model, control structures like `FOR` were earlier modeled so that they
|
781
|
+
looked like keywords. Nowadays they are considered totally different objects and
|
782
|
+
their keyword specific attributes `name`, `kwnane`, `libname`, `doc`, `args`,
|
783
|
+
`assign`, `tags` and `timeout` have been deprecated (`#4846`_).
|
784
|
+
|
785
|
+
- `starttime`, `endtime` and `elapsed` time attributes in the result model have been
|
786
|
+
silently deprecated (`#4258`_). Accessing them does not yet cause a deprecation
|
787
|
+
warning, but users are recommended to use `start_time`, `end_time` and
|
788
|
+
`elapsed_time` attributes that are available since Robot Framework 6.1.
|
789
|
+
|
790
|
+
- `kwname`, `libname` and `sourcename` attributes used by the `Keyword` object
|
791
|
+
in the result model have been silently deprecated (`#4884`_). New code should use
|
792
|
+
`name`, `owner` and `source_name` instead.
|
793
|
+
|
794
|
+
Other deprecated features
|
795
|
+
-------------------------
|
796
|
+
|
797
|
+
- Using embedded arguments with a variable that has a value not matching custom
|
798
|
+
embedded argument patterns nowadays causes a deprecation warning (`#4524`_).
|
799
|
+
Earlier variables used as embedded arguments were always accepted without
|
800
|
+
validating values.
|
801
|
+
|
802
|
+
- Using `FOR IN ZIP` loops with lists having different lengths without explicitly
|
803
|
+
using `mode=SHORTEST` has been deprecated (`#4685`_). The strict mode where lengths
|
804
|
+
must match will be the default mode in the future.
|
805
|
+
|
806
|
+
- Various utility functions in the `robot.utils` package that are no longer used
|
807
|
+
by Robot Framework itself, including the whole Python 2/3 compatibility layer,
|
808
|
+
have been deprecated (`#4501`_). If you need some of these utils, you can copy
|
809
|
+
their code to your own tool or library. This change may affect existing
|
810
|
+
libraries and tools in the ecosystem.
|
811
|
+
|
812
|
+
- `case_insensitive` and `whitespace_insensitive` arguments used by some
|
813
|
+
Collections and String library keywords have been deprecated in favor of
|
814
|
+
`ignore_case` and `ignore_whitespace`. The new arguments were added for
|
815
|
+
consistency reasons (`#4954`_) and the old arguments will continue to work
|
816
|
+
for the time being.
|
817
|
+
|
818
|
+
- Passing time as milliseconds to the `elapsed_time_to_string` utility function
|
819
|
+
has been deprecated (`#4862`_).
|
820
|
+
|
821
|
+
Acknowledgements
|
822
|
+
================
|
823
|
+
|
824
|
+
Robot Framework development is sponsored by the `Robot Framework Foundation`_
|
825
|
+
and its over 60 member organizations. If your organization is using Robot Framework
|
826
|
+
and benefiting from it, consider joining the foundation to support its
|
827
|
+
development as well.
|
828
|
+
|
829
|
+
Robot Framework 7.0 team funded by the foundation consists of `Pekka Klärck`_ and
|
830
|
+
`Janne Härkönen <https://github.com/yanne>`_ (part time).
|
831
|
+
In addition to work done by them, the community has provided some great contributions:
|
832
|
+
|
833
|
+
- `Ygor Pontelo <https://github.com/ygorpontelo>`__ added async support to the
|
834
|
+
dynamic and hybrid library APIs (`#4803`_) and fixed a bug with handling async
|
835
|
+
keywords when execution is stopped gracefully (`#4808`_).
|
836
|
+
|
837
|
+
- `Topi 'top1' Tuulensuu <https://github.com/totu>`__ fixed a performance regression
|
838
|
+
when using `Run Keyword` so that the name of the executed keyword contains a variable
|
839
|
+
(`#4659`_).
|
840
|
+
|
841
|
+
- `Pasi Saikkonen <https://github.com/psaikkonen>`__ added dark mode to reports
|
842
|
+
and logs (`#3725`_).
|
843
|
+
|
844
|
+
- `René <https://github.com/Snooz82>`__ added return type information to Libdoc's
|
845
|
+
HTML output (`#3017`_), fixed `DotDict` equality comparisons (`#4956`_) and
|
846
|
+
helped finalizing the dark mode support (`#3725`_).
|
847
|
+
|
848
|
+
- `Robin <https://github.com/robinmackaij>`__ added type hints to modules that
|
849
|
+
did not yet have them under the public `robot.api` package (`#4841`_).
|
850
|
+
|
851
|
+
- `Mark Moberts <https://github.com/MobyNL>`__ added case-insensitive list and
|
852
|
+
dictionary comparison support to the Collections library (`#4343`_).
|
853
|
+
|
854
|
+
- `Daniel Biehl <https://github.com/d-biehl>`__ enhanced performance of traversing
|
855
|
+
the parsing model using `ModelVisitor` (`#4934`_).
|
856
|
+
|
857
|
+
Big thanks to Robot Framework Foundation, to community members listed above, and to
|
858
|
+
everyone else who has tested preview releases, submitted bug reports, proposed
|
859
|
+
enhancements, debugged problems, or otherwise helped with Robot Framework 7.0
|
860
|
+
development.
|
861
|
+
|
862
|
+
See you at `RoboCon 2024 <https://robocon.io>`__ either onsite or online!
|
863
|
+
|
864
|
+
| `Pekka Klärck`_
|
865
|
+
| Robot Framework lead developer
|
866
|
+
|
867
|
+
Full list of fixes and enhancements
|
868
|
+
===================================
|
869
|
+
|
870
|
+
.. list-table::
|
871
|
+
:header-rows: 1
|
872
|
+
|
873
|
+
* - ID
|
874
|
+
- Type
|
875
|
+
- Priority
|
876
|
+
- Summary
|
877
|
+
* - `#3296`_
|
878
|
+
- enhancement
|
879
|
+
- critical
|
880
|
+
- Support keywords and control structures with listener version 3
|
881
|
+
* - `#3761`_
|
882
|
+
- enhancement
|
883
|
+
- critical
|
884
|
+
- Native `VAR` syntax to create variables inside tests and keywords
|
885
|
+
* - `#4294`_
|
886
|
+
- enhancement
|
887
|
+
- critical
|
888
|
+
- Drop Python 3.6 and 3.7 support
|
889
|
+
* - `#4710`_
|
890
|
+
- enhancement
|
891
|
+
- critical
|
892
|
+
- Support library keywords with both embedded and normal arguments
|
893
|
+
* - `#4847`_
|
894
|
+
- enhancement
|
895
|
+
- critical
|
896
|
+
- Support JSON serialization with result model
|
897
|
+
* - `#4659`_
|
898
|
+
- bug
|
899
|
+
- high
|
900
|
+
- Performance regression when using `Run Keyword` and keyword name contains a variable
|
901
|
+
* - `#4921`_
|
902
|
+
- bug
|
903
|
+
- high
|
904
|
+
- Log levels don't work correctly with `robot:flatten`
|
905
|
+
* - `#3725`_
|
906
|
+
- enhancement
|
907
|
+
- high
|
908
|
+
- Support dark theme with report and log
|
909
|
+
* - `#4258`_
|
910
|
+
- enhancement
|
911
|
+
- high
|
912
|
+
- Change timestamps from custom strings to `datetime` in result model and to ISO 8601 format in output.xml
|
913
|
+
* - `#4374`_
|
914
|
+
- enhancement
|
915
|
+
- high
|
916
|
+
- Support removing tags set globally by using `-tag` syntax with `[Tags]` setting
|
917
|
+
* - `#4633`_
|
918
|
+
- enhancement
|
919
|
+
- high
|
920
|
+
- Automatic argument conversion and validation for `Literal`
|
921
|
+
* - `#4711`_
|
922
|
+
- enhancement
|
923
|
+
- high
|
924
|
+
- Support type aliases in formats `'list[int]'` and `'int | float'` in argument conversion
|
925
|
+
* - `#4803`_
|
926
|
+
- enhancement
|
927
|
+
- high
|
928
|
+
- Async support to dynamic and hybrid library APIs
|
929
|
+
* - `#4808`_
|
930
|
+
- bug
|
931
|
+
- medium
|
932
|
+
- Async keywords are not stopped when execution is stopped gracefully
|
933
|
+
* - `#4859`_
|
934
|
+
- bug
|
935
|
+
- medium
|
936
|
+
- Parsing errors in reStructuredText files have no source
|
937
|
+
* - `#4880`_
|
938
|
+
- bug
|
939
|
+
- medium
|
940
|
+
- Initially empty test fails even if pre-run modifier adds content to it
|
941
|
+
* - `#4886`_
|
942
|
+
- bug
|
943
|
+
- medium
|
944
|
+
- `Set Variable If` is slow if it has several conditions
|
945
|
+
* - `#4898`_
|
946
|
+
- bug
|
947
|
+
- medium
|
948
|
+
- Resolving special variables can fail with confusing message
|
949
|
+
* - `#4915`_
|
950
|
+
- bug
|
951
|
+
- medium
|
952
|
+
- `cached_property` attributes are called when importing library
|
953
|
+
* - `#4924`_
|
954
|
+
- bug
|
955
|
+
- medium
|
956
|
+
- WHILE `on_limit` missing from listener v2 attributes
|
957
|
+
* - `#4926`_
|
958
|
+
- bug
|
959
|
+
- medium
|
960
|
+
- WHILE and TRY content are not removed with `--removekeywords all`
|
961
|
+
* - `#4945`_
|
962
|
+
- bug
|
963
|
+
- medium
|
964
|
+
- `TypedDict` with forward references do not work in argument conversion
|
965
|
+
* - `#4956`_
|
966
|
+
- bug
|
967
|
+
- medium
|
968
|
+
- DotDict behaves inconsistent on equality checks. `x == y` != `not x != y` and not `x != y` == `not x == y`
|
969
|
+
* - `#4964`_
|
970
|
+
- bug
|
971
|
+
- medium
|
972
|
+
- Variables set using `Set Suite Variable` with `children=True` cannot be properly overwritten
|
973
|
+
* - `#4980`_
|
974
|
+
- bug
|
975
|
+
- medium
|
976
|
+
- DateTime library uses deprecated `datetime.utcnow()`
|
977
|
+
* - `#4999`_
|
978
|
+
- bug
|
979
|
+
- medium
|
980
|
+
- XML Library: Double namespace during Element To String
|
981
|
+
* - `#5005`_
|
982
|
+
- bug
|
983
|
+
- medium
|
984
|
+
- `Log Variables` should not consume iterables
|
985
|
+
* - `#3017`_
|
986
|
+
- enhancement
|
987
|
+
- medium
|
988
|
+
- Add return type to Libdoc specs and HTML output
|
989
|
+
* - `#4103`_
|
990
|
+
- enhancement
|
991
|
+
- medium
|
992
|
+
- Process: Change the default `stdin` behavior from `subprocess.PIPE` to `None`
|
993
|
+
* - `#4302`_
|
994
|
+
- enhancement
|
995
|
+
- medium
|
996
|
+
- Remove `Reserved` library
|
997
|
+
* - `#4343`_
|
998
|
+
- enhancement
|
999
|
+
- medium
|
1000
|
+
- Collections: Support case-insensitive list and dictionary comparisons
|
1001
|
+
* - `#4375`_
|
1002
|
+
- enhancement
|
1003
|
+
- medium
|
1004
|
+
- Change token type of `AS` (or `WITH NAME`) used with library imports to `Token.AS`
|
1005
|
+
* - `#4385`_
|
1006
|
+
- enhancement
|
1007
|
+
- medium
|
1008
|
+
- Change the parsing model object produced by `Test Tags` (and `Force Tags`) to `TestTags`
|
1009
|
+
* - `#4432`_
|
1010
|
+
- enhancement
|
1011
|
+
- medium
|
1012
|
+
- Loudly deprecate singular section headers
|
1013
|
+
* - `#4501`_
|
1014
|
+
- enhancement
|
1015
|
+
- medium
|
1016
|
+
- Loudly deprecate old Python 2/3 compatibility layer and other deprecated utils
|
1017
|
+
* - `#4524`_
|
1018
|
+
- enhancement
|
1019
|
+
- medium
|
1020
|
+
- Loudly deprecate variables used as embedded arguments not matching custom patterns
|
1021
|
+
* - `#4545`_
|
1022
|
+
- enhancement
|
1023
|
+
- medium
|
1024
|
+
- Support creating assigned variable name based on another variable like `${${var}} = Keyword`
|
1025
|
+
* - `#4667`_
|
1026
|
+
- enhancement
|
1027
|
+
- medium
|
1028
|
+
- Remove deprecated constructs from Libdoc spec files
|
1029
|
+
* - `#4685`_
|
1030
|
+
- enhancement
|
1031
|
+
- medium
|
1032
|
+
- Deprecate `SHORTEST` mode being default with `FOR IN ZIP` loops
|
1033
|
+
* - `#4708`_
|
1034
|
+
- enhancement
|
1035
|
+
- medium
|
1036
|
+
- Use `assing`, not `variable`, with FOR and TRY/EXCEPT model objects when referring to assigned variables
|
1037
|
+
* - `#4720`_
|
1038
|
+
- enhancement
|
1039
|
+
- medium
|
1040
|
+
- Require `--suite parent.suite` to match the full suite name
|
1041
|
+
* - `#4721`_
|
1042
|
+
- enhancement
|
1043
|
+
- medium
|
1044
|
+
- Change behavior of `--test` and `--include` so that they are cumulative
|
1045
|
+
* - `#4747`_
|
1046
|
+
- enhancement
|
1047
|
+
- medium
|
1048
|
+
- Support `[Setup]` with user keywords
|
1049
|
+
* - `#4784`_
|
1050
|
+
- enhancement
|
1051
|
+
- medium
|
1052
|
+
- Remote: Enhance `datetime`, `date` and `timedelta` conversion
|
1053
|
+
* - `#4841`_
|
1054
|
+
- enhancement
|
1055
|
+
- medium
|
1056
|
+
- Add typing to all modules under `robot.api`
|
1057
|
+
* - `#4846`_
|
1058
|
+
- enhancement
|
1059
|
+
- medium
|
1060
|
+
- Result model: Loudly deprecate not needed attributes and remove already deprecated ones
|
1061
|
+
* - `#4872`_
|
1062
|
+
- enhancement
|
1063
|
+
- medium
|
1064
|
+
- Control continue-on-failure mode by using recursive and non-recursive tags together
|
1065
|
+
* - `#4876`_
|
1066
|
+
- enhancement
|
1067
|
+
- medium
|
1068
|
+
- Loudly deprecate `[Return]` setting
|
1069
|
+
* - `#4877`_
|
1070
|
+
- enhancement
|
1071
|
+
- medium
|
1072
|
+
- XML: Support ignoring element order with `Elements Should Be Equal`
|
1073
|
+
* - `#4883`_
|
1074
|
+
- enhancement
|
1075
|
+
- medium
|
1076
|
+
- Result model: Add `message` to keywords and control structures and remove `doc` from controls
|
1077
|
+
* - `#4884`_
|
1078
|
+
- enhancement
|
1079
|
+
- medium
|
1080
|
+
- Result model: Enhance storing keyword name
|
1081
|
+
* - `#4896`_
|
1082
|
+
- enhancement
|
1083
|
+
- medium
|
1084
|
+
- Support `separator=<value>` configuration option with scalar variables in Variables section
|
1085
|
+
* - `#4903`_
|
1086
|
+
- enhancement
|
1087
|
+
- medium
|
1088
|
+
- Support argument conversion and named arguments with dynamic variable files
|
1089
|
+
* - `#4905`_
|
1090
|
+
- enhancement
|
1091
|
+
- medium
|
1092
|
+
- Support creating variable name based on another variable like `${${VAR}}` in Variables section
|
1093
|
+
* - `#4910`_
|
1094
|
+
- enhancement
|
1095
|
+
- medium
|
1096
|
+
- Make listener v3 the default listener API
|
1097
|
+
* - `#4912`_
|
1098
|
+
- enhancement
|
1099
|
+
- medium
|
1100
|
+
- Parsing model: Move `type` and `tokens` from `_fields` to `_attributes`
|
1101
|
+
* - `#4930`_
|
1102
|
+
- enhancement
|
1103
|
+
- medium
|
1104
|
+
- BuiltIn: New `Reset Log Level` keyword for resetting the log level to the original value
|
1105
|
+
* - `#4939`_
|
1106
|
+
- enhancement
|
1107
|
+
- medium
|
1108
|
+
- Parsing model: Rename `Return` to `ReturnSetting` and `ReturnStatement` to `Return`
|
1109
|
+
* - `#4942`_
|
1110
|
+
- enhancement
|
1111
|
+
- medium
|
1112
|
+
- Add public argument conversion API for libraries and other tools
|
1113
|
+
* - `#4952`_
|
1114
|
+
- enhancement
|
1115
|
+
- medium
|
1116
|
+
- Collections: Make `ignore_order` and `ignore_keys` recursive
|
1117
|
+
* - `#4960`_
|
1118
|
+
- enhancement
|
1119
|
+
- medium
|
1120
|
+
- Support integer conversion with strings representing whole number floats like `'1.0'` and `'2e10'`
|
1121
|
+
* - `#4976`_
|
1122
|
+
- enhancement
|
1123
|
+
- medium
|
1124
|
+
- Support string `SELF` (case-insenstive) when library registers itself as listener
|
1125
|
+
* - `#4979`_
|
1126
|
+
- enhancement
|
1127
|
+
- medium
|
1128
|
+
- Add `robot.result.TestSuite.to/from_xml` methods
|
1129
|
+
* - `#4982`_
|
1130
|
+
- enhancement
|
1131
|
+
- medium
|
1132
|
+
- DateTime: Support `datetime.date` as an input format with date related keywords
|
1133
|
+
* - `#4983`_
|
1134
|
+
- enhancement
|
1135
|
+
- medium
|
1136
|
+
- Type conversion: Remove support for deprecated `ByteString`
|
1137
|
+
* - `#5000`_
|
1138
|
+
- enhancement
|
1139
|
+
- medium
|
1140
|
+
- Nicer API for setting keyword call arguments programmatically
|
1141
|
+
* - `#4934`_
|
1142
|
+
- ---
|
1143
|
+
- medium
|
1144
|
+
- Enhance performance of visiting parsing model
|
1145
|
+
* - `#4621`_
|
1146
|
+
- bug
|
1147
|
+
- low
|
1148
|
+
- OperatingSystem library docs have broken link / title
|
1149
|
+
* - `#4798`_
|
1150
|
+
- bug
|
1151
|
+
- low
|
1152
|
+
- `--removekeywords passed` doesn't remove test setup and teardown
|
1153
|
+
* - `#4867`_
|
1154
|
+
- bug
|
1155
|
+
- low
|
1156
|
+
- Original order of dictionaries is not preserved when they are pretty printed in log messages
|
1157
|
+
* - `#4870`_
|
1158
|
+
- bug
|
1159
|
+
- low
|
1160
|
+
- User keyword teardown missing from running model JSON schema
|
1161
|
+
* - `#4904`_
|
1162
|
+
- bug
|
1163
|
+
- low
|
1164
|
+
- Importing static variable file with arguments does not fail
|
1165
|
+
* - `#4913`_
|
1166
|
+
- bug
|
1167
|
+
- low
|
1168
|
+
- Trace log level logs arguments twice for embedded arguments
|
1169
|
+
* - `#4927`_
|
1170
|
+
- bug
|
1171
|
+
- low
|
1172
|
+
- WARN level missing from the log level selector in log.html
|
1173
|
+
* - `#4967`_
|
1174
|
+
- bug
|
1175
|
+
- low
|
1176
|
+
- Variables are not resolved in keyword name in WUKS error message
|
1177
|
+
* - `#4861`_
|
1178
|
+
- enhancement
|
1179
|
+
- low
|
1180
|
+
- Remove deprecated `accept_plain_values` from `timestr_to_secs` utility function
|
1181
|
+
* - `#4862`_
|
1182
|
+
- enhancement
|
1183
|
+
- low
|
1184
|
+
- Deprecate `elapsed_time_to_string` accepting time as milliseconds
|
1185
|
+
* - `#4864`_
|
1186
|
+
- enhancement
|
1187
|
+
- low
|
1188
|
+
- Process: Make warning about processes hanging if output buffers get full more visible
|
1189
|
+
* - `#4885`_
|
1190
|
+
- enhancement
|
1191
|
+
- low
|
1192
|
+
- Add `full_name` to replace `longname` to suite and test objects
|
1193
|
+
* - `#4900`_
|
1194
|
+
- enhancement
|
1195
|
+
- low
|
1196
|
+
- Make keywords and control structures in log look more like original data
|
1197
|
+
* - `#4922`_
|
1198
|
+
- enhancement
|
1199
|
+
- low
|
1200
|
+
- Change the log level of `Set Log Level` message from INFO to DEBUG
|
1201
|
+
* - `#4933`_
|
1202
|
+
- enhancement
|
1203
|
+
- low
|
1204
|
+
- Type conversion: Ignore hyphens when matching enum members
|
1205
|
+
* - `#4935`_
|
1206
|
+
- enhancement
|
1207
|
+
- low
|
1208
|
+
- Use `casefold`, not `lower`, when comparing strings case-insensitively
|
1209
|
+
* - `#4936`_
|
1210
|
+
- enhancement
|
1211
|
+
- low
|
1212
|
+
- Remove bytes support from `robot.utils.normalize` function
|
1213
|
+
* - `#4954`_
|
1214
|
+
- enhancement
|
1215
|
+
- low
|
1216
|
+
- Collections and String: Add `ignore_case` as alias for `case_insensitive`
|
1217
|
+
* - `#4958`_
|
1218
|
+
- enhancement
|
1219
|
+
- low
|
1220
|
+
- Document `robot_running` and `dry_run_active` properties of the BuiltIn library in the User Guide
|
1221
|
+
* - `#4975`_
|
1222
|
+
- enhancement
|
1223
|
+
- low
|
1224
|
+
- Support `times` and `x` suffixes with `WHILE` limit to make it more compatible with `Wait Until Keyword Succeeds`
|
1225
|
+
* - `#4988`_
|
1226
|
+
- enhancement
|
1227
|
+
- low
|
1228
|
+
- Change paths passed to listener v3 methods to `pathlib.Path` instances
|
1229
|
+
|
1230
|
+
Altogether 88 issues. View on the `issue tracker <https://github.com/robotframework/robotframework/issues?q=milestone%3Av7.0>`__.
|
1231
|
+
|
1232
|
+
.. _#3296: https://github.com/robotframework/robotframework/issues/3296
|
1233
|
+
.. _#3761: https://github.com/robotframework/robotframework/issues/3761
|
1234
|
+
.. _#4294: https://github.com/robotframework/robotframework/issues/4294
|
1235
|
+
.. _#4710: https://github.com/robotframework/robotframework/issues/4710
|
1236
|
+
.. _#4847: https://github.com/robotframework/robotframework/issues/4847
|
1237
|
+
.. _#4659: https://github.com/robotframework/robotframework/issues/4659
|
1238
|
+
.. _#4921: https://github.com/robotframework/robotframework/issues/4921
|
1239
|
+
.. _#3725: https://github.com/robotframework/robotframework/issues/3725
|
1240
|
+
.. _#4258: https://github.com/robotframework/robotframework/issues/4258
|
1241
|
+
.. _#4374: https://github.com/robotframework/robotframework/issues/4374
|
1242
|
+
.. _#4633: https://github.com/robotframework/robotframework/issues/4633
|
1243
|
+
.. _#4711: https://github.com/robotframework/robotframework/issues/4711
|
1244
|
+
.. _#4803: https://github.com/robotframework/robotframework/issues/4803
|
1245
|
+
.. _#4808: https://github.com/robotframework/robotframework/issues/4808
|
1246
|
+
.. _#4859: https://github.com/robotframework/robotframework/issues/4859
|
1247
|
+
.. _#4880: https://github.com/robotframework/robotframework/issues/4880
|
1248
|
+
.. _#4886: https://github.com/robotframework/robotframework/issues/4886
|
1249
|
+
.. _#4898: https://github.com/robotframework/robotframework/issues/4898
|
1250
|
+
.. _#4915: https://github.com/robotframework/robotframework/issues/4915
|
1251
|
+
.. _#4924: https://github.com/robotframework/robotframework/issues/4924
|
1252
|
+
.. _#4926: https://github.com/robotframework/robotframework/issues/4926
|
1253
|
+
.. _#4945: https://github.com/robotframework/robotframework/issues/4945
|
1254
|
+
.. _#4956: https://github.com/robotframework/robotframework/issues/4956
|
1255
|
+
.. _#4964: https://github.com/robotframework/robotframework/issues/4964
|
1256
|
+
.. _#4980: https://github.com/robotframework/robotframework/issues/4980
|
1257
|
+
.. _#4999: https://github.com/robotframework/robotframework/issues/4999
|
1258
|
+
.. _#5005: https://github.com/robotframework/robotframework/issues/5005
|
1259
|
+
.. _#3017: https://github.com/robotframework/robotframework/issues/3017
|
1260
|
+
.. _#4103: https://github.com/robotframework/robotframework/issues/4103
|
1261
|
+
.. _#4302: https://github.com/robotframework/robotframework/issues/4302
|
1262
|
+
.. _#4343: https://github.com/robotframework/robotframework/issues/4343
|
1263
|
+
.. _#4375: https://github.com/robotframework/robotframework/issues/4375
|
1264
|
+
.. _#4385: https://github.com/robotframework/robotframework/issues/4385
|
1265
|
+
.. _#4432: https://github.com/robotframework/robotframework/issues/4432
|
1266
|
+
.. _#4501: https://github.com/robotframework/robotframework/issues/4501
|
1267
|
+
.. _#4524: https://github.com/robotframework/robotframework/issues/4524
|
1268
|
+
.. _#4545: https://github.com/robotframework/robotframework/issues/4545
|
1269
|
+
.. _#4667: https://github.com/robotframework/robotframework/issues/4667
|
1270
|
+
.. _#4685: https://github.com/robotframework/robotframework/issues/4685
|
1271
|
+
.. _#4708: https://github.com/robotframework/robotframework/issues/4708
|
1272
|
+
.. _#4720: https://github.com/robotframework/robotframework/issues/4720
|
1273
|
+
.. _#4721: https://github.com/robotframework/robotframework/issues/4721
|
1274
|
+
.. _#4747: https://github.com/robotframework/robotframework/issues/4747
|
1275
|
+
.. _#4784: https://github.com/robotframework/robotframework/issues/4784
|
1276
|
+
.. _#4841: https://github.com/robotframework/robotframework/issues/4841
|
1277
|
+
.. _#4846: https://github.com/robotframework/robotframework/issues/4846
|
1278
|
+
.. _#4872: https://github.com/robotframework/robotframework/issues/4872
|
1279
|
+
.. _#4876: https://github.com/robotframework/robotframework/issues/4876
|
1280
|
+
.. _#4877: https://github.com/robotframework/robotframework/issues/4877
|
1281
|
+
.. _#4883: https://github.com/robotframework/robotframework/issues/4883
|
1282
|
+
.. _#4884: https://github.com/robotframework/robotframework/issues/4884
|
1283
|
+
.. _#4896: https://github.com/robotframework/robotframework/issues/4896
|
1284
|
+
.. _#4903: https://github.com/robotframework/robotframework/issues/4903
|
1285
|
+
.. _#4905: https://github.com/robotframework/robotframework/issues/4905
|
1286
|
+
.. _#4910: https://github.com/robotframework/robotframework/issues/4910
|
1287
|
+
.. _#4912: https://github.com/robotframework/robotframework/issues/4912
|
1288
|
+
.. _#4930: https://github.com/robotframework/robotframework/issues/4930
|
1289
|
+
.. _#4939: https://github.com/robotframework/robotframework/issues/4939
|
1290
|
+
.. _#4942: https://github.com/robotframework/robotframework/issues/4942
|
1291
|
+
.. _#4952: https://github.com/robotframework/robotframework/issues/4952
|
1292
|
+
.. _#4960: https://github.com/robotframework/robotframework/issues/4960
|
1293
|
+
.. _#4976: https://github.com/robotframework/robotframework/issues/4976
|
1294
|
+
.. _#4979: https://github.com/robotframework/robotframework/issues/4979
|
1295
|
+
.. _#4982: https://github.com/robotframework/robotframework/issues/4982
|
1296
|
+
.. _#4983: https://github.com/robotframework/robotframework/issues/4983
|
1297
|
+
.. _#5000: https://github.com/robotframework/robotframework/issues/5000
|
1298
|
+
.. _#4934: https://github.com/robotframework/robotframework/issues/4934
|
1299
|
+
.. _#4621: https://github.com/robotframework/robotframework/issues/4621
|
1300
|
+
.. _#4798: https://github.com/robotframework/robotframework/issues/4798
|
1301
|
+
.. _#4867: https://github.com/robotframework/robotframework/issues/4867
|
1302
|
+
.. _#4870: https://github.com/robotframework/robotframework/issues/4870
|
1303
|
+
.. _#4904: https://github.com/robotframework/robotframework/issues/4904
|
1304
|
+
.. _#4913: https://github.com/robotframework/robotframework/issues/4913
|
1305
|
+
.. _#4927: https://github.com/robotframework/robotframework/issues/4927
|
1306
|
+
.. _#4967: https://github.com/robotframework/robotframework/issues/4967
|
1307
|
+
.. _#4861: https://github.com/robotframework/robotframework/issues/4861
|
1308
|
+
.. _#4862: https://github.com/robotframework/robotframework/issues/4862
|
1309
|
+
.. _#4864: https://github.com/robotframework/robotframework/issues/4864
|
1310
|
+
.. _#4885: https://github.com/robotframework/robotframework/issues/4885
|
1311
|
+
.. _#4900: https://github.com/robotframework/robotframework/issues/4900
|
1312
|
+
.. _#4922: https://github.com/robotframework/robotframework/issues/4922
|
1313
|
+
.. _#4933: https://github.com/robotframework/robotframework/issues/4933
|
1314
|
+
.. _#4935: https://github.com/robotframework/robotframework/issues/4935
|
1315
|
+
.. _#4936: https://github.com/robotframework/robotframework/issues/4936
|
1316
|
+
.. _#4954: https://github.com/robotframework/robotframework/issues/4954
|
1317
|
+
.. _#4958: https://github.com/robotframework/robotframework/issues/4958
|
1318
|
+
.. _#4975: https://github.com/robotframework/robotframework/issues/4975
|
1319
|
+
.. _#4988: https://github.com/robotframework/robotframework/issues/4988
|