diff --git a/qase-robotframework/changelog.md b/qase-robotframework/changelog.md index 485609fd..bb800826 100644 --- a/qase-robotframework/changelog.md +++ b/qase-robotframework/changelog.md @@ -1,3 +1,10 @@ +# qase-robotframework 3.4.6 + +## What's new + +- Added support for parameters in user keywords. +- Added support for fields in user keywords. + # qase-robotframework 3.4.5 ## What's new diff --git a/qase-robotframework/changelog_new.md b/qase-robotframework/changelog_new.md deleted file mode 100644 index 91f66eff..00000000 --- a/qase-robotframework/changelog_new.md +++ /dev/null @@ -1,18 +0,0 @@ -# qase-robotframework 3.4.5 - -## What's new - -- Improved test failure status handling -- Enhanced error classification to distinguish assertion errors from other failures -- Assertion errors (containing keywords like 'assert', 'AssertionError', 'expect', 'should', 'must', 'equal', 'not equal') now map to `failed` status -- Non-assertion errors (setup failures, exceptions, etc.) now map to `invalid` status -- Updated dependency on qase-python-commons to version 3.5.5 - -## Migration Guide - -The listener now provides more accurate test result reporting by distinguishing between: -- `failed`: Test failed due to assertion error (test logic issue) -- `invalid`: Test failed due to non-assertion error (infrastructure/setup issue) - -This change provides better insights into test failures and helps identify whether issues are related to test logic or infrastructure problems. - diff --git a/qase-robotframework/docs/usage.md b/qase-robotframework/docs/usage.md index 92639f78..657ccb67 100644 --- a/qase-robotframework/docs/usage.md +++ b/qase-robotframework/docs/usage.md @@ -78,6 +78,28 @@ Browser Test Close browser ``` +### Adding Parameters and Fields to a User Keyword + +The `qase.params` tag can also be used in user keywords to specify which Robot Framework variables should be reported as parameters. + +```robotframework +*** Settings *** +Test Template Check Status + +*** Keywords *** +Check Status + [Arguments] ${module} + [Tags] qase.params:[module] qase.fields:{ "severity": "critical" } + Log Checking status of module: ${module} + +*** Test Cases *** +Check Status of BMS + [Tags] Q-20 qase.fields:{ "preconditions": "Module BMS is connected", "description": "Flash firmware to BMS module and check status" } + [Template] Check Status + BMS + +``` + --- ## Ignoring a Test in Qase diff --git a/qase-robotframework/pyproject.toml b/qase-robotframework/pyproject.toml index ac5d31f3..994ced13 100644 --- a/qase-robotframework/pyproject.toml +++ b/qase-robotframework/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "qase-robotframework" -version = "3.4.5" +version = "3.4.6" description = "Qase Robot Framework Plugin" readme = "README.md" authors = [{name = "Qase Team", email = "support@qase.io"}] diff --git a/qase-robotframework/src/qase/robotframework/listener.py b/qase-robotframework/src/qase/robotframework/listener.py index 9a3d80d9..9568578f 100644 --- a/qase-robotframework/src/qase/robotframework/listener.py +++ b/qase-robotframework/src/qase/robotframework/listener.py @@ -85,6 +85,25 @@ def start_test(self, test, result): self.runtime.result = Result(title=test.name, signature=test.name) self.runtime.steps = {} + def end_user_keyword(self, data, implementation, result): + logger.debug("Ending user keyword '%s'", data.name) + + test_metadata = TagParser.parse_tags(result.tags) + + if test_metadata.params: + # Get argument names from the implementation + args_names = implementation.args.argument_names if hasattr(implementation.args, 'argument_names') else [] + args_values = result.args if hasattr(result, 'args') else [] + params: dict = {} + for param in test_metadata.params: + if param in args_names: + params[param] = args_values[args_names.index(param)] + self.runtime.result.params = params + + if test_metadata.fields: + for key, value in test_metadata.fields.items(): + self.runtime.result.add_field(Field(key, value)) + def end_test(self, test, result): logger.debug("Finishing test '%s'", test.name) @@ -114,11 +133,12 @@ def end_test(self, test, result): steps = self.__parse_steps(result) self.runtime.result.add_steps(steps) - if len(test_metadata.params) > 0: - params: dict = {} + # Process parameters if they exist + if test_metadata.params: for param in test_metadata.params: - params[param] = BuiltIn().get_variable_value(f"${{{param}}}") - self.runtime.result.params = params + param_value = BuiltIn().get_variable_value(f"${{{param}}}") + if param_value is not None: + self.runtime.result.add_param(param, param_value) if hasattr(test, "doc"): self.runtime.result.add_field(Field("description", test.doc)) diff --git a/qase-robotframework/src/qase/robotframework/tag_parser.py b/qase-robotframework/src/qase/robotframework/tag_parser.py index 84e66033..82dc8ee2 100644 --- a/qase-robotframework/src/qase/robotframework/tag_parser.py +++ b/qase-robotframework/src/qase/robotframework/tag_parser.py @@ -49,7 +49,13 @@ def __extract_fields(tag: str) -> dict: def __extract_params(tag: str) -> list[str]: value = tag.split(':', 1)[-1].strip() try: - return [item.strip() for item in value[1:-1].split(",")] - except ValueError as e: + # Remove square brackets and split by comma + if value.startswith('[') and value.endswith(']'): + params_str = value[1:-1] + return [item.strip() for item in params_str.split(",") if item.strip()] + else: + # Handle case without brackets + return [item.strip() for item in value.split(",") if item.strip()] + except (ValueError, IndexError) as e: TagParser.__logger.error(f"Error parsing params from tag '{tag}': {e}") return []