Skip to content

Latest commit

 

History

History
1325 lines (1084 loc) · 52.9 KB

rf-6.1.rst

File metadata and controls

1325 lines (1084 loc) · 52.9 KB

Robot Framework 6.1

Robot Framework 6.1 is a new feature release with support for converting Robot Framework data to JSON and back, a new external parser API, possibility to mix embedded and normal arguments, and various other interesting new features both for normal users and for external tool developers.

Questions and comments related to the release can be sent to the robotframework-users mailing list or to Robot Framework Slack, and possible bugs submitted to the issue tracker.

If you have pip installed, just run

pip install --upgrade robotframework

to install the latest available release or use

pip install robotframework==6.1

to install exactly this version. Alternatively you can download the source distribution from PyPI and install it manually. For more details and other installation approaches, see the installation instructions.

Robot Framework 6.1 was released on Monday June 12, 2023. It was superseded by Robot Framework 6.1.1.

Most important enhancements

JSON data format

The biggest new feature in Robot Framework 6.1 is the possibility to convert test/task data to JSON and back (#3902). This functionality has three main use cases:

  • Transferring data between processes and machines. A suite can be converted to JSON in one machine and recreated somewhere else.
  • Saving a suite, possibly a nested suite, constructed from normal Robot Framework data into a single JSON file that is faster to parse.
  • Alternative data format for external tools generating tests or tasks.

This feature is designed more for tool developers than for regular Robot Framework users and we expect new interesting tools to emerge in the future. The main functionalities are explained below:

  1. You can serialize a suite structure into JSON by using TestSuite.to_json method. When used without arguments, it returns JSON data as a string, but it also accepts a path or an open file where to write JSON data along with configuration options related to JSON formatting:

    python

    from robot.running import TestSuite

    # Construct suite based on data on the file system. suite = TestSuite.from_file_system('/path/to/data')

    # Get JSON data as a string. data = suite.to_json()

    # Save JSON data to a file with custom indentation. suite.to_json('data.rbt', indent=2)

    If you would rather work with Python data and then convert that to JSON or some other format yourself, you can use TestSuite.to_dict instead.

  2. You can create a suite based on JSON data using TestSuite.from_json. It works both with JSON strings and paths to JSON files:

    python

    from robot.running import TestSuite

    # Create suite from JSON data in a file. suite = TestSuite.from_json('data.rbt')

    # Create suite from a JSON string. suite = TestSuite.from_json('{"name": "Suite", "tests": [{"name": "Test"}]}')

    If you have data as a Python dictionary, you can use TestSuite.from_dict instead.

  3. When executing tests or tasks using the robot command, JSON files with the custom .rbt extension are parsed automatically. This includes running individual JSON files like robot tests.rbt and running directories containing .rbt files.

Suite source information in the data got from TestSuite.to_json and TestSuite.to_dict is in absolute format. If a suite is recreated later on a different machine, the source may thus not match the directory structure on that machine. To avoid such problems, it is possible to use the new TestSuite.adjust_source method to make the suite source relative before getting the data and add a correct root directory after the suite is recreated:

python

from robot.running import TestSuite

# Create a suite, adjust source and convert to JSON. suite = TestSuite.from_file_system('/path/to/data') suite.adjust_source(relative_to='/path/to') suite.to_json('data.rbt')

# Recreate suite elsewhere and adjust source accordingly. suite = TestSuite.from_json('data.rbt') suite.adjust_source(root='/new/path/to')

Ths JSON serialization support can be enhanced in future Robot Framework versions. If you have an enhancement idea or believe you have encountered a bug, please submit an issue or start a discussion thread on the #devel channel on our Slack.

The JSON data format is documented using the running.json schema file.

External parser API

The parser API is another important new interface targeted for tool developers (#1283). It makes it possible to create custom parsers that can handle their own data formats or even override Robot Framework's own parser.

Parsers are taken into use from the command line using the new --parser option the same way as, for example, listeners. This includes specifying parsers as names or paths, giving arguments to parser classes, and so on:

robot --parser MyParser tests.custom
robot --parser path/to/MyParser.py tests.custom
robot --parser Parser1:arg --parser Parser2:a1:a2 path/to/tests

In simple cases parsers can be implemented as modules. They only thing they need is an EXTENSION or extension attribute that specifies the extension or extensions they support, and a parse method that gets the path of the source file to parse as an argument:

python

from robot.api import TestSuite

EXTENSION = '.example'

def parse(source):

suite = TestSuite(name='Example', source=source) test = suite.tests.create(name='Test') test.body.create_keyword(name='Log', args=['Hello!']) return suite

As the example demonstrates, the parse method must return a TestSuite instance. In the above example the suite contains only some dummy data and the source file is not actually parsed.

Parsers can also be implemented as classes which makes it possible for them to preserve state and allows passing arguments from the command like. The following example illustrates that and, unlike the previous example, actually processes the source file:

python

from pathlib import Path from robot.api import TestSuite

class ExampleParser:

def __init(self, extension: str):

self.extension = extension

def parse(self, source: Path) -> TestSuite:

suite = TestSuite(TestSuite.name_from_source(source), source=source) for line in source.read_text().splitlines(): test = suite.tests.create(name=line) test.body.create_keyword(name='Log', args=['Hello!']) return suite

As the earlier examples have demonstrated, parsers do not need to extend any explicit base class or interface. There is, however, an optional Parser base class that can be extended. The following example does that and has also two other differences compared to earlier examples:

  • The parser has optional parse_init file for parsing suite initialization files.
  • Both parse and parse_init accept optional defaults argument. When this second argument is present, the parse method gets a TestDefaults instance that contains possible test related default values (setup, teardown, tags and timeout) from initialization files. Also parse_init can get it and possible changes are seen by subsequently called parse methods.

python

from pathlib import Path from robot.api import TestSuite from robot.api.interfaces import Parser, TestDefaults

class ExampleParser(Parser):

extension = ('example', 'another')

def parse(self, source: Path, defaults: TestDefaults) -> TestSuite:

"""Create a suite and set possible defaults from init files to tests.""" suite = TestSuite(TestSuite.name_from_source(source), source=source) for line in source.read_text().splitlines(): test = suite.tests.create(name=line, doc='Example') test.body.create_keyword(name='Log', args=['Hello!']) defaults.set_to(test) return suite

def parse_init(self, source: Path, defaults: TestDefaults) -> TestSuite:

"""Create a dummy suite and set some defaults.

This method is called only if there is an initialization file with a supported extension. """ defaults.tags = ('tags', 'from init') defaults.setup = {'name': 'Log', 'args': ['Hello from init!']} return TestSuite(TestSuite.name_from_source(source.parent), doc='Example', source=source, metadata={'Example': 'Value'})

The final parser acts as a preprocessor for Robot Framework data files that supports headers in format === Test Cases === in addition to *** Test Cases ***. In this kind of usage it is convenient to use TestSuite.from_string, TestSuite.from_model or TestSuite.from_file_system factory methods for constructing the returned suite.

python

from pathlib import Path from robot.running import TestDefaults, TestSuite

class RobotPreprocessor:

extension = '.robot'

def parse(self, source: Path, defaults: TestDefaults) -> TestSuite:

data = source.read_text() for header in 'Settings', 'Variables', 'Test Cases', 'Keywords': data = data.replace(f'=== {header} ===', f'* {header}*') suite = TestSuite.from_string(data, defaults=defaults) return suite.config(name=TestSuite.name_from_source(source), source=source)

Python 3.12 compatibility

Python 3.12 will be released in October 2023. It contains a subtle change to tokenization that affects Robot Framework's Python evaluation when the special $var syntax is used. This issue has been fixed and Robot Framework 6.1 is also otherwise Python 3.12 compatible (#4771).

User keywords with both embedded and normal arguments

User keywords can nowadays mix embedded arguments and normal arguments (#4234). For example, this kind of usage is possible:

robotframework

* Test Cases* Example Number of horses is 2 Number of dogs is 3

* Keywords* Number of ${animals} is [Arguments] ${count} Log to console There are ${count} ${animals}.

This only works with user keywords at least for now. If there is interest, the support can be extended to library keywords in future releases.

Support item assignment with lists and dictionaries

Robot Framework 6.1 makes it possible to assign return values from keywords to list and dictionary items (#4546):

${list}[0] =    Keyword
${dict}[key] =    Keyword
${result}[users][0] =    Keyword

Possibility to flatten keyword structures during execution

With nested keyword structures, especially with recursive keyword calls and with WHILE and FOR loops, the log file can get hard to understand with many different nesting levels. Such nested structures also increase the size of the output.xml file. For example, even a simple keyword like:

robotframework

* Keywords* Example Log Robot Log Framework

creates this much content in output.xml:

xml

<kw name="Example">
<kw name="Log" library="BuiltIn">

<arg>Robot</arg> <doc>Logs the given message with the given level.</doc> <msg timestamp="20230103 20:06:36.663" level="INFO">Robot</msg> <status status="PASS" starttime="20230103 20:06:36.663" endtime="20230103 20:06:36.663"/>

</kw> <kw name="Log" library="BuiltIn"> <arg>Framework</arg> <doc>Logs the given message with the given level.</doc> <msg timestamp="20230103 20:06:36.663" level="INFO">Framework</msg> <status status="PASS" starttime="20230103 20:06:36.663" endtime="20230103 20:06:36.664"/> </kw> <status status="PASS" starttime="20230103 20:06:36.663" endtime="20230103 20:06:36.664"/>

</kw>

We already have the --flattenkeywords option for "flattening" such structures and it works great. When a keyword is flattened, its child keywords and control structures are removed otherwise, but all their messages (<msg> elements) are preserved. Using --flattenkeywords does not affect output.xml generated during execution, but flattening happens when output.xml files are parsed and can save huge amounts of memory. When --flattenkeywords is used with Rebot, it is possible to create a new flattened output.xml. For example, the above structure is converted into this if the Example keyword is flattened using `--flattenkeywords`:

xml

<kw name="Keyword">

<doc>_Content flattened._</doc> <msg timestamp="20230103 20:06:36.663" level="INFO">Robot</msg> <msg timestamp="20230103 20:06:36.663" level="INFO">Framework</msg> <status status="PASS" starttime="20230103 20:06:36.663" endtime="20230103 20:06:36.664"/>

</kw>

Starting from Robot Framework 6.1, this kind of flattening can be done also during execution and without using command line options. The only thing needed is using the new keyword tag robot:flatten (#4584) and flattening is done automatically. For example, if the earlier Keyword is changed to:

robotframework

* Keywords* Example [Tags] robot:flatten Log Robot Log Framework

the result in output.xml will be this:

xml

<kw name="Example">

<tag>robot:flatten</tag> <msg timestamp="20230317 00:54:34.772" level="INFO">Robot</msg> <msg timestamp="20230317 00:54:34.772" level="INFO">Framework</msg> <status status="PASS" starttime="20230317 00:54:34.771" endtime="20230317 00:54:34.772"/>

</kw>

The main benefit of using robot:flatten instead of --flattenkeywords is that it is used already during execution making the resulting output.xml file smaller. --flattenkeywords has more configuration options than robot:flatten, though, but robot:flatten can be enhanced in that regard later if there are needs.

Type information added to public APIs

Robot Framework has several public APIs that library and tool developers can use. These APIs nowadays have type hints making their usage easier:

  • The TestSuite structure used by listeners, model modifiers, external parsers, and various other tools (#4570)
  • Listener API (#4568)
  • Dynamic and hybrid library APIs (#4567)
  • Parsing API (#4740)
  • Visitor API (#4569)

Custom argument converters can access library

Support for custom argument converters was added in Robot Framework 5.0 (#4088) and they have turned out to be really useful. This functionality is now enhanced so that converters can easily get an access to the library containing the keyword that is used and can thus do conversion based on the library state (#4510). This can be done simply by creating a converter that accepts two values. The first value is the value used in the data, exactly as earlier, and the second is the library instance or module:

python

def converter(value, library):

...

Converters accepting only one argument keep working as earlier. There are no plans to require changing them to accept two values.

JSON variable file support

It has been possible to create variable files using YAML in addition to Python for long time, and nowadays also JSON variable files are supported (#4532). For example, a JSON file containing:

json

{

"STRING": "Hello, world!", "INTEGER": 42

}

could be used like this:

robotframework

* Settings* Variables example.json

* Test Cases* Example Should Be Equal ${STRING} Hello, world! Should Be Equal ${INTEGER} ${42}

WHILE loop enhancements

Robot Framework's WHILE loop has been enhanced in several different ways:

  • The biggest enhancement is that WHILE loops got an optional on_limit configuration option that controls what to do if the configured loop limit is reached (#4562). By default execution fails, but setting the option to PASS changes that. For example, the following loop runs ten times and continues execution afterwards:

    robotframework

    * Test Cases* WHILE with 'limit' and 'on_limit' WHILE True limit=10 on_limit=PASS Log to console Hello! END Log to console Hello once more!

  • The loop condition is nowadays optional (#4576). For example, the above loop header could be simplified to this:

    WHILE    limit=10   on_limit=PASS
  • New on_limit_message configuration option can be used to set the message that is used if the loop limit exceeds and the loop fails (#4575).
  • A bug with the loop limit in teardowns has been fixed (#4744).

FOR IN ZIP loop behavior if lists lengths differ can be configured

Robot Framework's FOR IN ZIP loop behaves like Python's zip function so that if lists lengths are not the same, items from longer ones are ignored. For example, the following loop is executed only twice:

robotframework

* Variables* @{ANIMALS} dog cat horse cow elephant @{ELÄIMET} koira kissa

* Test Cases* Example FOR ${en} ${fi} IN ZIP ${ANIMALS} ${ELÄIMET} Log ${en} is ${fi} in Finnish END

This behavior can cause problems when iterating over items received from the automated system. For example, the following test would pass regardless how many things Get something returns as long as the returned items match the expected values. The example succeeds if Get something returns ten items if three first ones match. What's even worse, it succeeds also if Get something returns nothing.

robotframework

* Test Cases* Example Validate something expected 1 expected 2 expected 3

* Keywords** Validate something [Arguments] @{expected} @{actual} = Get something FOR ${act} ${exp} IN ZIP ${actual} ${expected} Validate one thing ${act} ${exp} END

This situation is pretty bad because it can cause false positives where automation succeeds but nothing is actually done. Python itself has this same issue, and Python 3.10 added new optional strict argument to zip (PEP 681). In addition to that, Python has for long time had a separate zip_longest function that loops over all values possibly filling-in values to shorter lists.

To support the same features as Python, Robot Framework's FOR IN ZIP loops now have an optional mode configuration option that accepts three values (#4682):

  • `STRICT`: Lists must have equal lengths. If not, execution fails. This is the same as using strict=True with Python's zip function.
  • `SHORTEST`: Items in longer lists are ignored. Infinitely long lists are supported in this mode as long as one of the lists is exhausted. This is the current default behavior.
  • `LONGEST`: The longest list defines how many iterations there are. Missing values in shorter lists are filled-in with value specified using the fill option or None if it is not used. This is the same as using Python's zip_longest function except that it has fillvalue argument instead of fill.

All these modes are illustrated by the following examples:

robotframework

* Variables* @{CHARACTERS} a b c d f @{NUMBERS} 1 2 3

* Test Cases* STRICT mode [Documentation] This loop fails due to lists lengths being different. FOR ${c} ${n} IN ZIP ${CHARACTERS} ${NUMBERS} mode=STRICT Log ${c}: ${n} END

SHORTEST mode

[Documentation] This loop executes three times. FOR ${c} ${n} IN ZIP ${CHARACTERS} ${NUMBERS} mode=SHORTEST Log ${c}: ${n} END

LONGEST mode

[Documentation] This loop executes five times. ... On last two rounds ${n} has value None. FOR ${c} ${n} IN ZIP ${CHARACTERS} ${NUMBERS} mode=LONGEST Log ${c}: ${n} END

LONGEST mode with custom fill value

[Documentation] This loop executes five times. ... On last two rounds ${n} has value -. FOR ${c} ${n} IN ZIP ${CHARACTERS} ${NUMBERS} mode=LONGEST fill=- Log ${c}: ${n} END

This enhancement makes it easy to activate strict validation and avoid false positives. The default behavior is still problematic, though, and the plan is to change it to STRICT in the future. Those who want to keep using the SHORTEST mode need to enable it explicitly.

New pseudo log level CONSOLE

There are often needs to log something to the console while tests or tasks are running. Some keywords support it out-of-the-box and there is also separate Log To Console keyword for that purpose.

The new CONSOLE pseudo log level (#4536) adds this support to any keyword that accepts a log level such as Log List in Collections and Page Should Contain in SeleniumLibrary. When this level is used, the message is logged both to the console and on INFO level to the log file.

Configuring virtual root suite when running multiple suites

When execution multiple suites like robot first.robot second.robot, Robot Framework creates a virtual root suite containing the executed suites as child suites. Earlier this virtual suite could be configured only by using command line options like --name, but now it is possible to use normal suite initialization files (__init__.robot) for that purpose (#4015). If an initialization file is included in the call as in the following example, the root suite is configured based on data it contains:

robot __init__.robot first.robot second.robot

The most important feature this enhancement allows is specifying suite setup and teardown to the virtual root suite. Earlier that was not possible at all.

Support for asynchronous functions and methods as keywords

It is nowadays possible to use asynchronous functions (created using async def) as keywords just like normal functions (#4089). For example, the following async functions could be used as keyword Gather Something and `Async Sleep`:

python

from asyncio import gather, sleep

async def gather_something():

print('start') await gather(something(1), something(2), something(3)) print('done')

async def async_sleep(time: int):

await sleep(time)

zipapp compatibility

Robot Framework 6.1 is compatible with zipapp (#4613). This makes it possible to create standalone distributions using either only the zipapp module or with a help from an external packaging tool like PDM.

New translations

Robot Framework 6.0 started our localization efforts and added built-in support for various languages. Robot Framework 6.1 adds support for Vietnamese (#4792) and we hope to add more languages in the future.

The new Name setting (#4583) has also been translated to various languages but not yet for all. All supported languages and exact translations used by them are listed in the User Guide.

Backwards incompatible changes

We try to avoid backwards incompatible changes in general and especially in non-major version. They cannot always be avoided, though, and there are some features and fixes in this release that are not fully backwards compatible. These changes should not cause problems in normal usage, but especially tools using Robot Framework may nevertheless be affected.

Changes to output.xml

Syntax errors such as invalid settings like [Setpu] or END in a wrong place are nowadays reported better (#4683). Part of that change was storing invalid constructs in output.xml as <error> elements. Tools processing output.xml files so that they go through all elements need to take <error> elements into account, but tools just querying information using xpath expression or otherwise should not be affected.

Another change is that <for> and <while> elements may have new attributes. With FOR IN ENUMERATE loops the <for> element may get start attribute (#4684), with FOR IN ZIP loops the <for> element may get mode and fill attributes (#4682), and with WHILE loops the <while> element may get on_limit (#4562) and on_limit_message (#4575) attributes. This affects tools processing all possible attributes, but such tools ought to be very rare.

Changes to TestSuite model structure

The aforementioned enhancements for handling invalid syntax better (#4683) required changes also to the TestSuite model structure. Syntax errors are nowadays represented as Error objects and they can appear in the body of TestCase, Keyword, and other such model objects. Tools interacting with the TestSuite structure should take Error objects into account, but tools using the visitor API should in general not be affected.

Another related change is that doc, tags, timeout and teardown attributes were removed from the robot.running.Keyword object (#4589). They were left there accidentally and were not used for anything by Robot Framework. Tools accessing them need to be updated.

Finally, the TestSuite.source attribute is nowadays a pathlib.Path instance instead of a string (#4596).

Changes to parsing model

Invalid section headers like *** Bad *** are nowadays represented in the parsing model as InvalidSection objects when they earlier were generic Error objects (#4689).

New ReturnSetting object has been introduced as an alias for Return. This does not yet change anything, but in the future Return will be used for other purposes and tools using it should be updated to use ReturnSetting instead (#4656).

Files are not excluded from parsing when using --suite option

Earlier when the --suite option was used, files not matching the specified suite name were excluded from parsing altogether. This performance enhancement was convenient especially with bigger suite structures, but it needed to be removed (#4688) because the new Name setting (#4583) made it impossible to get the suite name solely based on the file name. Users who are affected by this change can use the new --parseinclude option that explicitly specifies which files should be parsed (#4687).

Changes to Libdoc spec files

Libdoc did not handle parameterized types like list[int] properly earlier. Fixing that problem required storing information about nested types into the spec files along with the top level type. In addition to the parameterized types, also unions are now handled differently than earlier, but with normal types there are no changes. With JSON spec files changes were pretty small, but XML spec files required a bit bigger changes. See issue #4538 for more details about what exactly has changed and how.

Argument conversion changes

If an argument has multiple types, Robot Framework tries to do argument conversion with all of them, from left to right, until one of them succeeds. Earlier if a type was not recognized at all, the used value was returned as-is without trying conversion with the remaining types. For example, if a keyword like:

python

def example(arg: Union[UnknownType, int]):

...

would be called like:

Example    42

the integer conversion would not be attempted and the keyword would get string 42. This was changed so that unrecognized types are just skipped and in the above case integer conversion is nowadays done (#4648). That obviously changes the value the keyword gets to an integer.

Another argument conversion change is that the Any type is now recognized so that any value is accepted without conversion (#4647). This change is mostly backwards compatible, but in a special case where such an argument has a default value like arg: Any = 1 the behavior changes. Earlier when Any was not recognized at all, conversion was attempted based on the default value type. Nowadays when Any is recognized and explicitly not converted, no conversion based on the default value is done either. The behavior change can be avoided by using arg: Union[int, Any] = 1 which is much better typing in general.

Changes affecting execution

Invalid settings in tests and keywords like [Tasg] are nowadays considered syntax errors that cause failures at execution time (#4683). They were reported also earlier, but they did not affect execution.

All invalid sections in resource files are considered to be syntax errors that prevent importing the resource file (#4689). Earlier having a *** Test Cases *** header in a resource file caused such an error, but other invalid headers were just reported as errors but imports succeeded.

Deprecated features

Python 3.7 support

Python 3.7 will reach its end-of-life in June 2023. We have decided to support it with Robot Framework 6.1 and its bug fix releases, but Robot Framework 7.0 will not support it anymore (#4637).

We have already earlier deprecated Python 3.6 that reached its end-of-life already in December 2021 the same way. The reason we still support it is that it is the default Python version in Red Hat Enterprise Linux 8 that is still actively supported.

Old elements in Libdoc spec files

Libdoc spec files have been enhanced in latest releases. For backwards compatibility reasons old information has been preserved, but all such data will be removed in Robot Framework 7.0. For more details about what will be removed see issue #4667.

Other deprecated features

  • Return node in the parsing model has been deprecated and ReturnSetting should be used instead (#4656).
  • name argument of TestSuite.from_model__ has been deprecated and will be removed in the future (#4598).
  • accept_plain_values argument of robot.utils.timestr_to_secs has been deprecated and will be removed in the future (#4522).

Acknowledgements

Robot Framework development is sponsored by the Robot Framework Foundation and its over 60 member organizations. If your organization is using Robot Framework and benefiting from it, consider joining the foundation to support its development as well.

Robot Framework 6.1 team funded by the foundation consists of Pekka Klärck and Janne Härkönen (part time). In addition to that, the community has provided several great contributions:

  • @Serhiy1 helped massively with adding type information to the TestSuite structure (#4570).
  • @Vincema added support for long command line options with hyphens like --pre-run-modifier (#4547) and implemented possibility to assign keyword return values directly to list and dictionary items (#4546).
  • @sunday2 implemented JSON variable file support (#4532) and fixed User Guide generation on Windows (#4680).
  • Tatu Aalto added positional-only argument support to the dynamic library API (#4660).
  • @otemek implemented possibility to give a custom name to a suite using a new Name setting (#4583).
  • @franzhaas made Robot Framework zipapp compatible (#4613).
  • Ygor Pontelo added support for using asynchronous functions and methods as keywords (#4089).
  • @ursa-h enhanced keyword conflict resolution so that library search order has higher precedence (#4609).
  • Jonathan Arns and Fabian Zeiher made the initial implementation to limit which files are parsed (#4687).
  • @asaout added on_limit_message option to WHILE loops to control the failure message used if the loop limit is exceeded (#4575).
  • @turunenm implemented CONSOLE pseudo log level (#4536).
  • Yuri Verweij enhanced Dictionaries Should Be Equal so that it supports ignoring keys (#2717).
  • Hưng Trịnh provided Vietnamese translation (#4792) and Elout van Leeuwen helped with localization otherwise.

Big thanks to Robot Framework Foundation for the continued support, to community members listed above for their valuable contributions, and to everyone else who has submitted bug reports, proposed enhancements, debugged problems, or otherwise helped to make Robot Framework 6.1 such a great release!

Pekka Klärck
Robot Framework Creator

Full list of fixes and enhancements

ID Type Priority Summary
#1283 enhancement critical External parser API for custom parsers
#3902 enhancement critical Support serializing executable suite into JSON
#4234 enhancement critical Support user keywords with both embedded and normal arguments
#4771 enhancement critical Python 3.12 compatibility
#4705 bug high Items are not converted when using generics like list[int] and passing object, not string
#4744 bug high WHILE limit doesn't work in teardown
#4015 enhancement high Support configuring virtual suite created when running multiple suites with __init__.robot
#4089 enhancement high Support asynchronous functions and methods as keywords
#4510 enhancement high Make it possible for custom converters to get access to the library
#4532 enhancement high JSON variable file support
#4536 enhancement high Add new pseudo log level CONSOLE that logs to console and to log file
#4546 enhancement high Support item assignment with lists and dicts like ${x}[key] = Keyword
#4562 enhancement high Possibility to continue execution after WHILE limit is reached
#4570 enhancement high Add type information to TestSuite structure
#4584 enhancement high New robot:flatten tag for "flattening" keyword structures
#4613 enhancement high Make Robot Framework compatible with zipapp
#4637 enhancement high Deprecate Python 3.7
#4682 enhancement high Make FOR IN ZIP loop behavior if lists have different lengths configurable
#4746 enhancement high Decide and document XDG media type
#4792 enhancement high Add Vietnamese translation
#4538 bug medium Libdoc doesn't handle parameterized types like list[int] properly
#4571 bug medium Suite setup and teardown are executed even if all tests are skipped
#4589 bug medium Remove unused attributes from robot.running.Keyword model object
#4604 bug medium Listeners do not get source information for keywords executed with Run Keyword
#4626 bug medium Inconsistent argument conversion when using None as default value with Python 3.11 and earlier
#4635 bug medium Dialogs created by Dialogs on Windows don't have focus
#4648 bug medium Argument conversion should be attempted with all possible types even if some type wouldn't be recognized
#4670 bug medium Parsing model: Documentation.from_params(...).value doesn't work
#4680 bug medium User Guide generation broken on Windows
#4689 bug medium Invalid sections are not represented properly in parsing model
#4692 bug medium ELSE IF condition not passed to listeners
#4695 bug medium Accessing id property of model objects may cause ValueError
#4716 bug medium Variable nodes with nested variables report a parsing error, but work properly in the runtime
#4754 bug medium Back navigation does not work properly in HTML outputs (log, report, Libdoc)
#4756 bug medium Failed keywords inside skipped tests are not expanded
#2717 enhancement medium Dictionaries Should Be Equal should support ignoring keys
#3579 enhancement medium Enhance performance of selecting tests using --include and --exclude
#4210 enhancement medium Enhance error detection at parsing time
#4547 enhancement medium Support long command line options with hyphens like --pre-run-modifier
#4567 enhancement medium Add optional typed base class for dynamic library API
#4568 enhancement medium Add optional typed base classes for listener API
#4569 enhancement medium Add type information to the visitor API
#4575 enhancement medium Add on_limit_message option to WHILE loops to control message used if loop limit is exceeded
#4576 enhancement medium Make the WHILE loop condition optional
#4583 enhancement medium Possibility to give a custom name to a suite using Name setting
#4601 enhancement medium Add robot.running.TestSuite.from_string method
#4609 enhancement medium If multiple keywords match, resolve conflict first using search order
#4627 enhancement medium Support custom converters that accept only *varargs
#4647 enhancement medium Add explicit argument converter for Any that does no conversion
#4660 enhancement medium Dynamic API: Support positional-only arguments
#4666 enhancement medium Add public API to query is Robot running and is dry-run active
#4676 enhancement medium Propose using $var syntax if evaluation IF or WHILE condition using ${var} fails
#4683 enhancement medium Report syntax errors better in log file
#4684 enhancement medium Handle start index with FOR IN ENUMERATE loops already in parser
#4687 enhancement medium Add explicit command line option to limit which files are parsed
#4688 enhancement medium Do not exclude files during parsing if using --suite option
#4729 enhancement medium Leading and internal spaces should be preserved in documentation
#4740 enhancement medium Add type hints to parsing API
#4765 enhancement medium Add forward compatible start_time, end_time and elapsed_time propertys to result objects
#4777 enhancement medium Parse files with .robot.rst extension automatically
#4793 enhancement medium Enhance programmatic API to create resource files
#4611 bug low Some unit tests cannot be run independently
#4634 bug low Dialogs created by Dialogs are not centered and their minimum size is too small
#4638 bug low Using bare Union as annotation is not handled properly
#4646 bug low Bad error message when function is annotated with an empty tuple ()
#4663 bug low BuiltIn.Log documentation contains a defect
#4736 bug low Backslash preventing newline in documentation can form escape sequence like \n
#4749 bug low Process: Split/Join Command Line do not work properly with pathlib.Path objects
#4780 bug low Libdoc crashes if it does not detect documentation format
#4781 bug low Libdoc: Type info for TypedDict doesn't list Mapping in converted types
#4522 enhancement low Deprecate accept_plain_values argument used by timestr_to_secs
#4596 enhancement low Make TestSuite.source attribute pathlib.Path instance
#4598 enhancement low Deprecate name argument of TestSuite.from_model
#4619 enhancement low Dialogs created by Dialogs should bind Enter key to OK button
#4636 enhancement low Buttons in dialogs created by Dialogs should get keyboard shortcuts
#4656 enhancement low Deprecate Return node in parsing model
#4709 enhancement low Add __repr__() method to NormalizedDict

Altogether 77 issues. View on the issue tracker.