diff --git a/.gitignore b/.gitignore index b1b98e12..2cd29527 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ results .vscode .devcontainer .venv +Syllabus.pdf \ No newline at end of file diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..58c4de6b --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,9 @@ +repos: + - repo: local + hooks: + - id: gen-numbering + name: Ensure numbering, TOC, and links are in sync + entry: python tools/gen_numbering.py + language: system + pass_filenames: false + always_run: true diff --git a/CONTRIBUTION.md b/CONTRIBUTION.md new file mode 100644 index 00000000..d11f6ae9 --- /dev/null +++ b/CONTRIBUTION.md @@ -0,0 +1,40 @@ +# Contributing + +Thanks for helping us improve the RFCP syllabus! The notes below explain how to bootstrap the tooling, run Docusaurus locally, and keep the docs consistent. + +## 1. Install prerequisites +- Node.js 20+ (needed for Docusaurus and Playwright) +- Python 3.11+ (the repo bootstrap script creates a virtual environment for you) +- npm (ships with Node) + +## 2. Project setup +1. From the repository root, bootstrap both the Python and JavaScript toolchains: + ```bash + python bootstrap.py + ``` + The script upgrades `pip`, installs `pre-commit`, and asks whether you want to pull in the optional PDF toolchain (Robot Framework + Browser batteries from `requirements.txt`, plus Chromium via `rfbrowser install chromium`). Answer "y" only if you plan to regenerate the PDF. Regardless of that choice, the script installs the pre-commit hook and then runs `npm install` inside `website/` so Docusaurus has its dependencies. +2. Start Docusaurus in development mode while you edit: + ```bash + cd website # if not already there + npm run start + ``` + +## 3. Quality checks before committing +- `pre-commit` automatically runs `python tools/gen_numbering.py` on every commit. If headings, learning-objective numbering, or internal links change the hook updates the files, prints a diff, and blocks the commit until you stage the fixes. +- All fenced code blocks must stay within 100 characters per line. Run `npm run build` in the `website/` directory to check code block line lengths (or let CI run it). +- Docusaurus validates internal links during builds. Run `npm run build` before submitting a PR to catch broken anchors or missing pages early. + +## 4. Generating the syllabus PDF +To rebuild the syllabus PDF from the Robot Framework assets, run the Robot Framework suite from the repo root: + +1. Activate the created virtual environment so local commands use the same interpreters as the hooks: + - macOS/Linux: `source .venv/bin/activate` + - Windows (PowerShell): `.venv\Scripts\Activate.ps1` + +2. Run the suite to generate the PDF: + ```bash + robot -d results tools/gen_pdf.robot + ``` +The PDF and execution logs land inside `results/`. + +Following the steps above keeps your local environment consistent with CI and ensures contributions land cleanly. Happy writing! diff --git a/LOs.csv b/LOs.csv index 4a98f376..f072ba2f 100644 --- a/LOs.csv +++ b/LOs.csv @@ -1,136 +1,136 @@ -LO ID,K Level,Content,Slide Number,Done,Notes -LO-1.1,(K1),Recall the two main use cases of Robot Framework,,, -LO-1.1.1,(K1),Recall the test levels Robot Framework is mostly used for,,, -LO-1.2.1,(K1),Recall the layers of the Generic Test Automation Architecture (gTAA) and their corresponding components in Robot Framework,,, -LO-1.2.2,(K1),Recall what is part of Robot Framework and what is not,,, -LO-1.2.3,(K1),Recall the technology Robot Framework is built on and the prerequisites for running it,,, -LO-1.3,(K1),Recall the key attributes of the syntax that makes Robot Framework simple and human-readable,,, -LO-1.3.3,(K2),Explain the difference between User Keywords and Library Keywords,,, -LO-1.3.4,(K1),Recall the difference between Resource Files and Libraries and their artifacts,,, -LO-1.4,(K1),Recall the three specification styles of Robot Framework,,, -LO-1.4.1,(K2),Understand the basic concepts of Keyword-Driven Specification,,, -LO-1.4.2,(K2),Understand the basic concepts of Behavior-Driven Specification,,, -LO-1.4.3,(K1),Recall the differences between Keyword-Driven and Behavior-Driven Specification,,, -LO-1.4.4,(K1),Recall the purpose of Data-Driven Specification,,, -LO-1.5.1,(K1),Recall the type of open-source license under which Robot Framework is distributed,,, -LO-1.5.2,(K1),List and recall the key objectives and organizational form of the Robot Framework Foundation,,, -LO-1.5.3,(K1),Recall the official webpages for Robot Framework and its resources,,, -LO-2.1,(K2),Understand which files and directories are considered suites and how they are structured in a suite tree.,,, -LO-2.1.1,(K1),Recall the conditions and requirements for a file to be considered a Suite file,,, -LO-2.1.2,(K1),Recall the available sections in a suite file and their purpose.,,, -LO-2.1.2.1-1,(K1),Recall the available settings in a suite file.,,, -LO-2.1.2.1-2,(K2),Understand the concepts of suite settings and how to define them.,,, -LO-2.1.2.2,(K1),Recall the purpose of the `*** Variables ***` section.,,, -LO-2.1.2.3,(K2),Understand the purpose of the `*** Test Cases ***` or `*** Tasks ***` section.,,, -LO-2.1.2.4,(K2),Understand the purpose and limitations of the `*** Keywords ***` section.,,, -LO-2.2,(K2),Understand the basic syntax of test cases and tasks.,,, -LO-2.2.1,(K3),Understand and apply the mechanics of indentation and separation in Robot Framework.,,, -LO-2.2.2,(K3),Be able to use line breaks and continuation in a statement.,,, -LO-2.2.3,(K3),Be able to add in-line comments to suites.,,, -LO-2.2.4,(K2),Understand how to escape control characters in Robot Framework.,,, -LO-2.2.5,(K2),Understand the structure of a basic suite file.,,, -LO-2.3,(K1),Recall the three components of the Robot Framework CLI.,,, -LO-2.3.1,(K2),Understand how to run the `robot` command and its basic usage.,,, -LO-2.3.2,(K2),Explain the execution artifacts generated by Robot Framework.,,, -LO-2.3.3,(K1),Recall the four different status labels used by Robot Framework.,,, -LO-2.3.3.1,(K2),Understand when an element is marked as `PASS`.,,, -LO-2.3.3.2,(K2),Understand when an element is marked as `FAIL`.,,, -LO-2.3.4,(K2),Understand the difference between log messages and console output.,,, -LO-2.4.1-1,(K1),Recall the purpose of keyword libraries and how to import them.,,, -LO-2.4.1-2,(K1),Recall the three types of libraries in Robot Framework.,,, -LO-2.4.2-1,(K1),Recall the purpose of resource files.,,, -LO-2.4.2-2,(K3),Use resource files to import new keywords.,,, -LO-2.4.3,(K2),Understand the different types of paths that can be used to import libraries and resource files.,,, -LO-2.5,(K2),Understand the structure of keyword interfaces and how to interpret keyword documentation.,,, -LO-2.5.1,(K1),Recall the information that can be found in a keyword documentation.,,, -LO-2.5.2,(K2),Understand the difference between argument kinds.,,, -LO-2.5.2.1,(K2),Understand the concept of mandatory arguments and how they are documented.,,, -LO-2.5.2.2,(K2),Understand the concept of optional arguments and how they are documented.,,, -LO-2.5.2.3,(K1),Recall the concept of keywords with embedded arguments used in Behavior-Driven Specification and how they are documented.,,, -LO-2.5.2.4,(K1),"Recall how ""Positional or Named Arguments"" are marked in the documentation and their use case.",,, -LO-2.5.2.5,(K1),"Recall how ""Variable Number of Positional Arguments"" are marked in the documentation and their use case.",,, -LO-2.5.2.6,(K1),"Recall what properties ""Named-Only Arguments"" have and how they are documented.",,, -LO-2.5.2.7,(K1),Recall how free named arguments are marked in documentation.,,, -LO-2.5.2.8,(K2),Understand the concept of argument types and automatic type conversion.,,, -LO-2.5.2.9,(K2),Understand the concept of return type hints.,,, -LO-2.5.3,(K2),Understand how to read keyword documentation and how to interpret the examples.,,, -LO-2.6,(K2),Understand how to call imported keywords and how to structure keyword calls.,,, -LO-2.6.1,(K2),Understand the concept of how to set argument values positionally.,,, -LO-2.6.2,(K2),Understand the concept of named arguments and how to set argument values by their name.,,, -LO-2.6.3,(K1),Recall how to use embedded arguments.,,, -LO-3.2-1,(K2),Understand how variables in Robot Framework are used to store and manage data,,, -LO-3.2-2,(K1),Recall the relevant five different ways to create and assign variables,,, -LO-3.2.1-1,(K1),Recall the four syntactical access types to variables with their prefixes,,, -LO-3.2.1-2,(K1),Recall the basic syntax of variables,,, -LO-3.2.2-1,(K3),Create variables in the Variables section,,, -LO-3.2.2-2,(K3),Use the correct variable prefixes for assigning and accessing variables,,, -LO-3.2.2.1-1,(K3),Create and assign scalar variables,,, -LO-3.2.2.1-2,(K2),Understand how multiple lines can be used to define scalar variables,,, -LO-3.2.2.2,(K2),Understand how to access primitive data types,,, -LO-3.2.2.3,(K2),Understand how to set and access data in list variables,,, -LO-3.2.2.4,(K2),Understand how to set and access data in dict variables,,, -LO-3.2.3,(K3),Be able to assign return values from keywords to variables,,, -LO-3.2.4,(K2),Understand how to create variables using the VAR statement,,, -LO-3.2.5,(K2),Understand how `local` and `suite` scope variables are created,,, -LO-3.3.2,(K1),Recall the rules how keyword names are matched.,,, -LO-3.3.3,(K1),Recall all available settings and their purpose for User Keywords,,, -LO-3.3.4,(K1),Recall the significance of the first logical line and in keyword documentation for the log file.,,, -LO-3.3.5,(K2),Understand the purpose and syntax of the [Arguments] setting in User Keywords.,,, -LO-3.3.5.1-1,(K1),Recall what makes an argument mandatory in a user keyword.,,, -LO-3.3.5.1-2,(K3),Define User Keywords with mandatory arguments.,,, -LO-3.3.5.2-1,(K1),Recall how to define optional arguments in a user keyword.,,, -LO-3.3.5.2-2,(K3),Define User Keywords with optional arguments.,,, -LO-3.3.5.3-1,(K2),Describe how embedded arguments are replaced by actual values during keyword execution.,,, -LO-3.3.5.3-2,(K2),Understand the role of embedded arguments in Behavior-Driven Development (BDD) style.,,, -LO-3.3.6-1,(K2),Understand how the `RETURN` statement passes data between different keywords.,,, -LO-3.3.6-2,(K3),Use the `RETURN` statement to return values from a user keyword and assign it to a variable.,,, -LO-3.3.7,(K1),Recall the naming conventions for user keywords.,,, -LO-3.4,(K2),Understand the basic concept and syntax of Data-Driven Specification,,, -LO-3.4.1-1,(K2),Understand how to define and use test|task templates,,, -LO-3.4.1-2,(K1),Recall the differences between the two different approaches to define Data-Driven Specification,,, -LO-3.4.1.1,(K1),Recall the syntax and properties of multiple named test|task with one template,,, -LO-3.4.1.2,(K1),Recall the syntax and properties of named test|task with multiple data rows,,, -LO-3.5,(K1),Recall that naming conflicts can arise from the import of multiple resource files.,,, -LO-3.5.1,(K2),Understand how transitive imports of resource files and libraries work.,,, -LO-3.5.2,(K3),Be able to configure a library import using arguments.,,, -LO-3.5.3,(K2),Explain how naming conflicts can happen and how to mitigate them.,,, -LO-4.1-1,(K1),Recall the purpose and benefits of Setups in Robot Framework,,, -LO-4.1-2,(K1),Recall the different levels where a Setup can be defined,,, -LO-4.1.1-1,(K1),"Recall key characteristics, benefits, and syntax of Suite Setup",,, -LO-4.1.1-2,(K2),Understand when Suite Setup is executed and used,,, -LO-4.1.2-1,(K1),"Recall key characteristics, benefits, and syntax of Test Setup",,, -LO-4.1.2-2,(K2),Understand when Test|Task Setup is executed and used,,, -LO-4.1.3,(K1),Recall key characteristics and syntax of Keyword Setup,,, -LO-4.2-1,(K2),Understand the different levels where and how Teardowns can be defined and when they are executed,,, -LO-4.2-2,(K1),Recall the typical use cases for using Teardowns,,, -LO-4.2.1-1,(K1),"Recall key characteristics, benefits, and syntax of Suite Teardown",,, -LO-4.2.1-2,(K2),Understand when Suite Teardown is executed and used,,, -LO-4.2.2-1,(K1),"Recall key characteristics, benefits, and syntax of Test|Task Teardown",,, -LO-4.2.2-2,(K2),Understand when Test|Task Teardown is executed and used,,, -LO-4.2.3,(K1),"Recall key characteristics, benefits, and syntax of Keyword Teardown",,, -LO-4.3,(K1),Recall how to define an Initialization Files and its purpose,,, -LO-4.3.2,(K2),Understand the execution order of Suite Setup and Suite Teardown in Initialization Files and their sub-suites and tests|tasks,,, -LO-4.3.3,(K1),Recall the allowed sections and their content in Initialization Files,,, -LO-4.4,(K1),Recall the purpose of Test|Task Tags in Robot Framework,,, -LO-4.4.1,(K1),Recall the syntax and different ways to assign tags to tests|tasks,,, -LO-4.4.2,(K2),Understand how to filter tests|tasks using the command-line interface of Robot Framework,,, -LO-4.5-1,(K1),Recall the use case and purpose of skipping tests|tasks in Robot Framework,,, -LO-4.5-2,(K1),Recall the different ways to skip tests|tasks in Robot Framework,,, -LO-4.5.1,(K1),Recall the differences between skip and exclude,,, -LO-5.1.1,(K2),Understand the difference between statically defined and dynamically created variables in Robot Framework,,, -LO-5.1.1.1,(K1),Recall the priority of statically defined or imported variables in Robot Framework,,, -LO-5.1.1.2,(K1),Recall the priority of dynamically created variables in Robot Framework,,, -LO-5.1.2,(K1),Recall the different variable scopes in Robot Framework,,, -LO-5.1.2.1,(K1),Recall how to define global variables and where they can be accessed,,, -LO-5.1.2.2,(K1),Recall how to define suite variables and where they can be accessed,,, -LO-5.1.2.3,(K1),Recall how to define test|task variables and where they can be accessed,,, -LO-5.1.2.4,(K1),Recall how to define local variables and where they can be accessed,,, -LO-5.1.4.1,(K1),Recall that assignments to `@{list}` variables convert values to lists automatically,,, -LO-5.1.4.2,(K1),Recall that `@{list}` unpacks the values of a list variable when accessed,,, -LO-5.1.5.1,(K1),Recall that assignments to `&{dict}` variables automatically convert values to Robot Framework Dictionaries and enable dot-access,,, -LO-5.1.5.2,(K1),Recall that `&{dict}` unpacks to multiple key=value pairs when accessed,,, -LO-5.1.6,(K1),Recall that Robot Framework provides access to execution information via Built-In variables,,, -LO-5.2.1,(K2),Understand the purpose and basic concept of IF-Statements,,, -LO-5.2.4,(K2),Understand the purpose and basic concept of FOR Loops,,, -LO-5.2.5,(K2),Understand the purpose and basic concept of WHILE Loops,,, -LO-5.2.6,(K2),Understand the purpose and basic concept of the BREAK and CONTINUE statements,,, +LO ID,K Level,Content,Slide Number,Done,Notes +LO-1.1,(K1),Recall the two main use cases of Robot Framework,,, +LO-1.1.1,(K1),Recall the test levels Robot Framework is mostly used for,,, +LO-1.2.1,(K1),Recall the layers of the Generic Test Automation Architecture (gTAA) and their corresponding components in Robot Framework,,, +LO-1.2.2,(K1),Recall what is part of Robot Framework and what is not,,, +LO-1.2.3,(K1),Recall the technology Robot Framework is built on and the prerequisites for running it,,, +LO-1.3,(K1),Recall the key attributes of the syntax that makes Robot Framework simple and human-readable,,, +LO-1.3.3,(K2),Explain the difference between User Keywords and Library Keywords,,, +LO-1.3.4,(K1),Recall the difference between Resource Files and Libraries and their artifacts,,, +LO-1.4,(K1),Recall the three specification styles of Robot Framework,,, +LO-1.4.1,(K2),Understand the basic concepts of Keyword-Driven Specification,,, +LO-1.4.2,(K2),Understand the basic concepts of Behavior-Driven Specification,,, +LO-1.4.3,(K1),Recall the differences between Keyword-Driven and Behavior-Driven Specification,,, +LO-1.4.4,(K1),Recall the purpose of Data-Driven Specification,,, +LO-1.5.1,(K1),Recall the type of open-source license under which Robot Framework is distributed,,, +LO-1.5.2,(K1),List and recall the key objectives and organizational form of the Robot Framework Foundation,,, +LO-1.5.3,(K1),Recall the official webpages for Robot Framework and its resources,,, +LO-2.1,(K2),Understand which files and directories are considered suites and how they are structured in a suite tree.,,, +LO-2.1.1,(K1),Recall the conditions and requirements for a file to be considered a Suite file,,, +LO-2.1.2,(K1),Recall the available sections in a suite file and their purpose.,,, +LO-2.1.2.1-1,(K1),Recall the available settings in a suite file.,,, +LO-2.1.2.1-2,(K2),Understand the concepts of suite settings and how to define them.,,, +LO-2.1.2.2,(K1),Recall the purpose of the `*** Variables ***` section.,,, +LO-2.1.2.3,(K2),Understand the purpose of the `*** Test Cases ***` or `*** Tasks ***` section.,,, +LO-2.1.2.4,(K2),Understand the purpose and limitations of the `*** Keywords ***` section.,,, +LO-2.2,(K2),Understand the basic syntax of test cases and tasks.,,, +LO-2.2.1,(K3),Understand and apply the mechanics of indentation and separation in Robot Framework.,,, +LO-2.2.2,(K3),Be able to use line breaks and continuation in a statement.,,, +LO-2.2.3,(K3),Be able to add in-line comments to suites.,,, +LO-2.2.4,(K2),Understand how to escape control characters in Robot Framework.,,, +LO-2.2.5,(K2),Understand the structure of a basic suite file.,,, +LO-2.3,(K1),Recall the three components of the Robot Framework CLI.,,, +LO-2.3.1,(K2),Understand how to run the `robot` command and its basic usage.,,, +LO-2.3.2,(K2),Explain the execution artifacts generated by Robot Framework.,,, +LO-2.3.3,(K1),Recall the four different status labels used by Robot Framework.,,, +LO-2.3.3.1,(K2),Understand when an element is marked as `PASS`.,,, +LO-2.3.3.2,(K2),Understand when an element is marked as `FAIL`.,,, +LO-2.3.4,(K2),Understand the difference between log messages and console output.,,, +LO-2.4.1-1,(K1),Recall the purpose of keyword libraries and how to import them.,,, +LO-2.4.1-2,(K1),Recall the three types of libraries in Robot Framework.,,, +LO-2.4.2-1,(K1),Recall the purpose of resource files.,,, +LO-2.4.2-2,(K3),Use resource files to import new keywords.,,, +LO-2.4.3,(K2),Understand the different types of paths that can be used to import libraries and resource files.,,, +LO-2.5,(K2),Understand the structure of keyword interfaces and how to interpret keyword documentation.,,, +LO-2.5.1,(K1),Recall the information that can be found in a keyword documentation.,,, +LO-2.5.2,(K2),Understand the difference between argument kinds.,,, +LO-2.5.2.1,(K2),Understand the concept of mandatory arguments and how they are documented.,,, +LO-2.5.2.2,(K2),Understand the concept of optional arguments and how they are documented.,,, +LO-2.5.2.3,(K1),Recall the concept of keywords with embedded arguments used in Behavior-Driven Specification and how they are documented.,,, +LO-2.5.2.4,(K1),"Recall how ""Positional or Named Arguments"" are marked in the documentation and their use case.",,, +LO-2.5.2.5,(K1),"Recall how ""Variable Number of Positional Arguments"" are marked in the documentation and their use case.",,, +LO-2.5.2.6,(K1),"Recall what properties ""Named-Only Arguments"" have and how they are documented.",,, +LO-2.5.2.7,(K1),Recall how free named arguments are marked in documentation.,,, +LO-2.5.2.8,(K2),Understand the concept of argument types and automatic type conversion.,,, +LO-2.5.2.9,(K2),Understand the concept of return type hints.,,, +LO-2.5.3,(K2),Understand how to read keyword documentation and how to interpret the examples.,,, +LO-2.6,(K2),Understand how to call imported keywords and how to structure keyword calls.,,, +LO-2.6.1,(K2),Understand the concept of how to set argument values positionally.,,, +LO-2.6.2,(K2),Understand the concept of named arguments and how to set argument values by their name.,,, +LO-2.6.3,(K1),Recall how to use embedded arguments.,,, +LO-3.2-1,(K2),Understand how variables in Robot Framework are used to store and manage data,,, +LO-3.2-2,(K1),Recall the relevant five different ways to create and assign variables,,, +LO-3.2.1-1,(K1),Recall the four syntactical access types to variables with their prefixes,,, +LO-3.2.1-2,(K1),Recall the basic syntax of variables,,, +LO-3.2.2-1,(K3),Create variables in the Variables section,,, +LO-3.2.2-2,(K3),Use the correct variable prefixes for assigning and accessing variables,,, +LO-3.2.2.1-1,(K3),Create and assign scalar variables,,, +LO-3.2.2.1-2,(K2),Understand how multiple lines can be used to define scalar variables,,, +LO-3.2.2.2,(K2),Understand how to access primitive data types,,, +LO-3.2.2.3,(K2),Understand how to set and access data in list variables,,, +LO-3.2.2.4,(K2),Understand how to set and access data in dict variables,,, +LO-3.2.3,(K3),Be able to assign return values from keywords to variables,,, +LO-3.2.4,(K2),Understand how to create variables using the VAR statement,,, +LO-3.2.5,(K2),Understand how `local` and `suite` scope variables are created,,, +LO-3.3.2,(K1),Recall the rules how keyword names are matched.,,, +LO-3.3.3,(K1),Recall all available settings and their purpose for User Keywords,,, +LO-3.3.4,(K1),Recall the significance of the first logical line and in keyword documentation for the log file.,,, +LO-3.3.5,(K2),Understand the purpose and syntax of the [Arguments] setting in User Keywords.,,, +LO-3.3.5.1-1,(K1),Recall what makes an argument mandatory in a user keyword.,,, +LO-3.3.5.1-2,(K3),Define User Keywords with mandatory arguments.,,, +LO-3.3.5.2-1,(K1),Recall how to define optional arguments in a user keyword.,,, +LO-3.3.5.2-2,(K3),Define User Keywords with optional arguments.,,, +LO-3.3.5.3-1,(K2),Describe how embedded arguments are replaced by actual values during keyword execution.,,, +LO-3.3.5.3-2,(K2),Understand the role of embedded arguments in Behavior-Driven Development (BDD) style.,,, +LO-3.3.6-1,(K2),Understand how the `RETURN` statement passes data between different keywords.,,, +LO-3.3.6-2,(K3),Use the `RETURN` statement to return values from a user keyword and assign it to a variable.,,, +LO-3.3.7,(K1),Recall the naming conventions for user keywords.,,, +LO-3.4,(K2),Understand the basic concept and syntax of Data-Driven Specification,,, +LO-3.4.1-1,(K2),Understand how to define and use test|task templates,,, +LO-3.4.1-2,(K1),Recall the differences between the two different approaches to define Data-Driven Specification,,, +LO-3.4.1.1,(K1),Recall the syntax and properties of multiple named test|task with one template,,, +LO-3.4.1.2,(K1),Recall the syntax and properties of named test|task with multiple data rows,,, +LO-3.5,(K1),Recall that naming conflicts can arise from the import of multiple resource files.,,, +LO-3.5.1,(K2),Understand how transitive imports of resource files and libraries work.,,, +LO-3.5.2,(K3),Be able to configure a library import using arguments.,,, +LO-3.5.3,(K2),Explain how naming conflicts can happen and how to mitigate them.,,, +LO-4.1-1,(K1),Recall the purpose and benefits of Setups in Robot Framework,,, +LO-4.1-2,(K1),Recall the different levels where a Setup can be defined,,, +LO-4.1.1-1,(K1),"Recall key characteristics, benefits, and syntax of Suite Setup",,, +LO-4.1.1-2,(K2),Understand when Suite Setup is executed and used,,, +LO-4.1.2-1,(K1),"Recall key characteristics, benefits, and syntax of Test Setup",,, +LO-4.1.2-2,(K2),Understand when Test|Task Setup is executed and used,,, +LO-4.1.3,(K1),Recall key characteristics and syntax of Keyword Setup,,, +LO-4.2-1,(K2),Understand the different levels where and how Teardowns can be defined and when they are executed,,, +LO-4.2-2,(K1),Recall the typical use cases for using Teardowns,,, +LO-4.2.1-1,(K1),"Recall key characteristics, benefits, and syntax of Suite Teardown",,, +LO-4.2.1-2,(K2),Understand when Suite Teardown is executed and used,,, +LO-4.2.2-1,(K1),"Recall key characteristics, benefits, and syntax of Test|Task Teardown",,, +LO-4.2.2-2,(K2),Understand when Test|Task Teardown is executed and used,,, +LO-4.2.3,(K1),"Recall key characteristics, benefits, and syntax of Keyword Teardown",,, +LO-4.3,(K1),Recall how to define Initialization Files and its purpose,,, +LO-4.3.2,(K2),Understand the execution order of Suite Setup and Suite Teardown in Initialization Files and their sub-suites and tests|tasks,,, +LO-4.3.3,(K1),Recall the allowed sections and their content in Initialization Files,,, +LO-4.4,(K1),Recall the purpose of Test|Task Tags in Robot Framework,,, +LO-4.4.1,(K1),Recall the syntax and different ways to assign tags to tests|tasks,,, +LO-4.4.2,(K2),Understand how to filter tests|tasks using the command-line interface of Robot Framework,,, +LO-4.5-1,(K1),Recall the use case and purpose of skipping tests|tasks in Robot Framework,,, +LO-4.5-2,(K1),Recall the different ways to skip tests|tasks in Robot Framework,,, +LO-4.5.1,(K1),Recall the differences between skip and exclude,,, +LO-5.1.1,(K2),Understand the difference between statically defined and dynamically created variables in Robot Framework,,, +LO-5.1.1.1,(K1),Recall the priority of statically defined or imported variables in Robot Framework,,, +LO-5.1.1.2,(K1),Recall the priority of dynamically created variables in Robot Framework,,, +LO-5.1.2,(K1),Recall the different variable scopes in Robot Framework,,, +LO-5.1.2.1,(K1),Recall how to define global variables and where they can be accessed,,, +LO-5.1.2.2,(K1),Recall how to define suite variables and where they can be accessed,,, +LO-5.1.2.3,(K1),Recall how to define test|task variables and where they can be accessed,,, +LO-5.1.2.4,(K1),Recall how to define local variables and where they can be accessed,,, +LO-5.1.4.1,(K1),Recall that assignments to `@{list}` variables convert values to lists automatically,,, +LO-5.1.4.2,(K1),Recall that `@{list}` unpacks the values of a list variable when accessed,,, +LO-5.1.5.1,(K1),Recall that assignments to `&{dict}` variables automatically convert values to Robot Framework Dictionaries and enable dot-access,,, +LO-5.1.5.2,(K1),Recall that `&{dict}` unpacks to multiple key=value pairs when accessed,,, +LO-5.1.6,(K1),Recall that Robot Framework provides access to execution information via Built-In variables,,, +LO-5.2.1,(K2),Understand the purpose and basic concept of IF-Statements,,, +LO-5.2.4,(K2),Understand the purpose and basic concept of FOR Loops,,, +LO-5.2.5,(K2),Understand the purpose and basic concept of WHILE Loops,,, +LO-5.2.6,(K2),Understand the purpose and basic concept of the BREAK and CONTINUE statements,,, diff --git a/README.md b/README.md index 53033095..0c81f8cc 100644 --- a/README.md +++ b/README.md @@ -46,16 +46,16 @@ - LO-2.1.1 (K1) Recall the conditions and requirements for a file to be considered a Suite file - [`2.1.2 Sections and Their Artifacts`](website/docs/chapter-02/01_suitefile.md#212-sections-and-their-artifacts) - LO-2.1.2 (K1) Recall the available sections in a suite file and their purpose. - - [`2.1.2.1 Introduction in `*** Settings ***` Section`](website/docs/chapter-02/01_suitefile.md#2121-introduction-to--settings--section) + - [`2.1.2.1 Introduction to `*** Settings ***` Section`](website/docs/chapter-02/01_suitefile.md#2121-introduction-to--settings--section) - LO-2.1.2.1-1 (K1) Recall the available settings in a suite file. - LO-2.1.2.1-2 (K2) Understand the concepts of suite settings and how to define them. - - [`2.1.2.2 Introduction in `*** Variables ***` Section`](website/docs/chapter-02/01_suitefile.md#2122-introduction-to--variables--section) + - [`2.1.2.2 Introduction to `*** Variables ***` Section`](website/docs/chapter-02/01_suitefile.md#2122-introduction-to--variables--section) - LO-2.1.2.2 (K1) Recall the purpose of the `*** Variables ***` section. - - [`2.1.2.3 Introduction in `*** Test Cases ***` or `*** Tasks ***` Section`](website/docs/chapter-02/01_suitefile.md#2123-introduction-to--test-cases--or--tasks--section) + - [`2.1.2.3 Introduction to `*** Test Cases ***` or `*** Tasks ***` Section`](website/docs/chapter-02/01_suitefile.md#2123-introduction-to--test-cases--or--tasks--section) - LO-2.1.2.3 (K2) Understand the purpose of the `*** Test Cases ***` or `*** Tasks ***` section. - - [`2.1.2.4 Introduction in `*** Keywords ***` Section`](website/docs/chapter-02/01_suitefile.md#2124-introduction-to--keywords--section) + - [`2.1.2.4 Introduction to `*** Keywords ***` Section`](website/docs/chapter-02/01_suitefile.md#2124-introduction-to--keywords--section) - LO-2.1.2.4 (K2) Understand the purpose and limitations of the `*** Keywords ***` section. - - [`2.1.2.5 Introduction in `*** Comments ***` Section`](website/docs/chapter-02/01_suitefile.md#2125-introduction-to--comments--section) + - [`2.1.2.5 Introduction to `*** Comments ***` Section`](website/docs/chapter-02/01_suitefile.md#2125-introduction-to--comments--section) - [`2.2 Basic Suite File Syntax`](website/docs/chapter-02/02_suitefile_syntax.md) - LO-2.2 (K2) Understand the basic syntax of test cases and tasks. - [`2.2.1 Separation and Indentation`](website/docs/chapter-02/02_suitefile_syntax.md#221-separation-and-indentation) @@ -222,7 +222,7 @@ - [`4.2.3 Keyword Teardown`](website/docs/chapter-04/02_teardowns.md#423-keyword-teardown) - LO-4.2.3 (K1) Recall key characteristics, benefits, and syntax of Keyword Teardown - [`4.3 Initialization Files`](website/docs/chapter-04/03_init_files.md) -- LO-4.3 (K1) Recall how to define an Initialization Files and its purpose +- LO-4.3 (K1) Recall how to define Initialization Files and its purpose - [`4.3.1 Purpose of Initialization Files`](website/docs/chapter-04/03_init_files.md#431-purpose-of-initialization-files) - [`4.3.2 Suite Setup and Suite Teardown of Initialization Files`](website/docs/chapter-04/03_init_files.md#432-suite-setup-and-suite-teardown-of-initialization-files) - LO-4.3.2 (K2) Understand the execution order of Suite Setup and Suite Teardown in Initialization Files and their sub-suites and tests|tasks @@ -282,7 +282,7 @@ - [`5.2.1 IF Statements`](website/docs/chapter-05/02_control_structures.md#521-if-statements) - LO-5.2.1 (K2) Understand the purpose and basic concept of IF-Statements - [`5.2.1.1 Basic IF Syntax`](website/docs/chapter-05/02_control_structures.md#5211-basic-if-syntax) -- [`5.2.2 IF/ELSE IF/ELSE Structure`](website/docs/chapter-05/02_control_structures.md#522-ifelse-ifelse-structure) +- [`5.2.2 IF/ELSE Structure`](website/docs/chapter-05/02_control_structures.md#522-ifelse-structure) - [`5.2.3 Inline IF Statement`](website/docs/chapter-05/02_control_structures.md#523-inline-if-statement) - [`5.2.4 FOR Loops`](website/docs/chapter-05/02_control_structures.md#524-for-loops) - LO-5.2.4 (K2) Understand the purpose and basic concept of FOR Loops diff --git a/Syllabus.pdf b/Syllabus.pdf index a0f5a458..396b349c 100644 Binary files a/Syllabus.pdf and b/Syllabus.pdf differ diff --git a/bootstrap.py b/bootstrap.py new file mode 100644 index 00000000..6941d7f8 --- /dev/null +++ b/bootstrap.py @@ -0,0 +1,86 @@ +import platform +import subprocess +from pathlib import Path +from venv import EnvBuilder + + +class Colors: + """ANSI color codes""" + + BLACK = "\033[0;30m" + RED = "\033[0;31m" + GREEN = "\033[0;32m" + BROWN = "\033[0;33m" + BLUE = "\033[0;34m" + PURPLE = "\033[0;35m" + CYAN = "\033[0;36m" + LIGHT_GRAY = "\033[0;37m" + DARK_GRAY = "\033[1;30m" + LIGHT_RED = "\033[1;31m" + LIGHT_GREEN = "\033[1;32m" + YELLOW = "\033[1;33m" + LIGHT_BLUE = "\033[1;34m" + LIGHT_PURPLE = "\033[1;35m" + LIGHT_CYAN = "\033[1;36m" + LIGHT_WHITE = "\033[1;37m" + BOLD = "\033[1m" + FAINT = "\033[2m" + ITALIC = "\033[3m" + UNDERLINE = "\033[4m" + BLINK = "\033[5m" + NEGATIVE = "\033[7m" + CROSSED = "\033[9m" + END = "\033[0m" + # cancel SGR codes if we don't write to a terminal + if not __import__("sys").stdout.isatty(): + for attr in dir(): + if not attr.startswith("_"): + if isinstance(getattr(__class__, attr), str): + setattr(__class__, attr, "") + elif __import__("platform").system() == "Windows": + kernel32 = __import__("ctypes").windll.kernel32 + kernel32.SetConsoleMode(kernel32.GetStdHandle(-11), 7) + del kernel32 + + +venv_dir = Path() / ".venv" +requirements_file = Path("requirements.txt") +website_dir = Path("website") +if not platform.platform().startswith("Windows"): + venv_bin = venv_dir / "bin" + venv_python = venv_bin / "python" + venv_pre_commit = venv_bin / "pre-commit" +else: + venv_bin = venv_dir / "Scripts" + venv_python = venv_bin / "python.exe" + venv_pre_commit = venv_bin / "pre-commit.exe" + +if not venv_dir.exists(): + print(f"Creating virtualenv in {venv_dir}") + EnvBuilder(with_pip=True).create(venv_dir) + +subprocess.run([venv_python, "-m", "pip", "install", "-U", "pip"], check=True) +subprocess.run([venv_python, "-m", "pip", "install", "-U", "pre-commit"], check=True) +install_pdf_tooling = False +if requirements_file.exists(): + answer = input(f"{Colors.GREEN}Install Robot Framework + browser batteries for PDF generation?{Colors.END} {Colors.YELLOW}[y/N]: {Colors.END}").strip().lower() + install_pdf_tooling = answer in {"y", "yes"} + if install_pdf_tooling: + subprocess.run([venv_python, "-m", "pip", "install", "-r", str(requirements_file)], check=True) + subprocess.run([venv_python, "-m", "Browser.entry", "install", "chromium", "--with-deps"], check=True) + +subprocess.run([venv_pre_commit, "install"], check=True) + +if website_dir.exists(): + npm_cmd = ["npm", "install"] + print(f"Running {' '.join(npm_cmd)} in {website_dir}") + subprocess.run(npm_cmd, cwd=website_dir, check=True) + +activate_script = ( + "source .venv/bin/activate" + if not platform.platform().startswith("Windows") + else ".venv\\Scripts\\activate" +) + +print(f"\n\nVirtualenv '{Colors.GREEN}{venv_dir}{Colors.END}' is ready and up-to-date.") +print(f"Run '{Colors.GREEN}{activate_script}{Colors.END}' to activate the virtualenv.") diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 00000000..92280c67 --- /dev/null +++ b/requirements.txt @@ -0,0 +1,2 @@ +robotframework-browser-batteries +pypdf diff --git a/tools/README.md b/tools/README.md new file mode 100644 index 00000000..8b137891 --- /dev/null +++ b/tools/README.md @@ -0,0 +1 @@ + diff --git a/tools/gen_pdf.robot b/tools/gen_pdf.robot index 46ac6e50..f6ecff33 100644 --- a/tools/gen_pdf.robot +++ b/tools/gen_pdf.robot @@ -5,6 +5,8 @@ Library Process *** Variables *** @{EXCLUDE_FROM_PDF} Example Questions +${BROWSER} chromium +${HEADLESS} ${True} *** Test Cases *** @@ -22,7 +24,11 @@ Build Docusaurus Process.Start Process npm run serve alias=docusaurus cwd=website Open Syllabus - New Browser chromium headless=False + IF $BROWSER.lower() in ['chrome', 'msedge'] + New Browser chromium channel=${BROWSER} headless=${HEADLESS} + ELSE + New Browser chromium headless=${HEADLESS} + END New Page http://localhost:3000/robotframework-RFCP-syllabus/docs/overview ${dark} Get Element States ... button[aria-label="Switch between dark and light mode (currently dark mode)"] diff --git a/website/docs/chapter-02/02_suitefile_syntax.md b/website/docs/chapter-02/02_suitefile_syntax.md index 6d60faba..dd49fa1f 100644 --- a/website/docs/chapter-02/02_suitefile_syntax.md +++ b/website/docs/chapter-02/02_suitefile_syntax.md @@ -18,7 +18,7 @@ Understand the basic syntax of test cases and tasks. :::: Suite files and resource files share the same syntax, however they differ in their capabilities. -Resource files are explained in more detail in [2.4.2 Resource Files](04_keyword_imports.md#242-resource-files) [3.1 Resource File Structure](../chapter-03/01_resource_file.md). +Resource files are explained in more detail in [2.4.2 Resource Files](chapter-02/04_keyword_imports.md#242-resource-files) [3.1 Resource File Structure](chapter-03/01_resource_file.md). ## 2.2.1 Separation and Indentation @@ -284,7 +284,7 @@ Resource keywords.resource Login User With Password Connect To Server Login User ironman 1234567890 # Login with valid credentials - Verify Valid Login Tony Stark # Verify that the login was successful by checking the user name + Verify Valid Login Tony Stark # Verifies a successful login by checking the user name Close Server Connection Denied Login With Wrong Password diff --git a/website/docs/chapter-02/03_executing.md b/website/docs/chapter-02/03_executing.md index f1edcb11..61fad30d 100644 --- a/website/docs/chapter-02/03_executing.md +++ b/website/docs/chapter-02/03_executing.md @@ -14,7 +14,7 @@ Robot Framework comes with three executables when being installed which are desi - `robot` is the main executable that is used to execute suites. - `rebot` (not part of this syllabus) is used to post-process execution results and generate reports. -- `libdoc` (not part of this syllabus) is used to generate keyword documentation for libraries and resource files. See [2.5 Keyword Interface and Documentation](../chapter-02/05_keyword_interface.md) +- `libdoc` (not part of this syllabus) is used to generate keyword documentation for libraries and resource files. See [2.5 Keyword Interface and Documentation](chapter-02/05_keyword_interface.md) @@ -37,7 +37,7 @@ At a basic level, you can run `robot` by providing the path to a suite file or s robot ``` -In case of the [2.2.5 Example Suite File](../chapter-02/02_suitefile_syntax.md#225-example-suite-file) where a single suite file named `TestSuite.robot` is stored in a directory `robot_files`, to execute the example test suite the following command is used, if the current working directory of the terminal is the directory containing the `robot_files` directory: +In case of the [2.2.5 Example Suite File](chapter-02/02_suitefile_syntax.md#225-example-suite-file) where a single suite file named `TestSuite.robot` is stored in a directory `robot_files`, to execute the example test suite the following command is used, if the current working directory of the terminal is the directory containing the `robot_files` directory: ```plaintext > robot robot_files ``` diff --git a/website/docs/chapter-02/04_keyword_imports.md b/website/docs/chapter-02/04_keyword_imports.md index c905eada..5d10225a 100644 --- a/website/docs/chapter-02/04_keyword_imports.md +++ b/website/docs/chapter-02/04_keyword_imports.md @@ -81,7 +81,7 @@ Use resource files to import new keywords. As mentioned before resource files are used to organize and store keywords and variables that are used in multiple suites. They share a similar structure and the same syntax as suite files, but they do not contain test cases or tasks. -See [2.2 Basic Suite File Syntax](chapter-02/02_suitefile_syntax.md) for more information about the structure of suite files and [3.1 Resource File Structure](../chapter-03/01_resource_file.md) for more details of their structure. +See [2.2 Basic Suite File Syntax](chapter-02/02_suitefile_syntax.md) for more information about the structure of suite files and [3.1 Resource File Structure](chapter-03/01_resource_file.md) for more details of their structure. They can contain other keyword imports, which cause the keywords from the imported libraries or resource files to be available in the suites where the resource file is imported. The same applies for variables that are defined and imported from other resource files. Therefore keywords from a library that have been imported in a resource file are also available in the suite that imports that resource file. diff --git a/website/docs/chapter-02/05_keyword_interface.md b/website/docs/chapter-02/05_keyword_interface.md index c4e8c71d..0c7e9304 100644 --- a/website/docs/chapter-02/05_keyword_interface.md +++ b/website/docs/chapter-02/05_keyword_interface.md @@ -70,7 +70,7 @@ All of them can be called positionally or by name. ![Run Process Keyword Documentation](/img/Run_Process_Docs.png) -This keyword has one :term[Mandatory Arguments]{tooltipMd="An **Argument** that must be set.
See [Mandatory Args](../chapter-03/03_user_keyword.md)"} `command` which can be called positionally or by name. +This keyword has one :term[Mandatory Arguments]{tooltipMd="An **Argument** that must be set.
See [Mandatory Args](chapter-03/03_user_keyword.md)"} `command` which can be called positionally or by name. The latter two arguments are optional. The argument `arguments` is a "Variable Number of Positional Arguments" and can only be set by position. @@ -346,7 +346,7 @@ Example redirecting stdout and stderr to a file: ```robotframework *** Test Cases *** Send 5 IPv4 Pings On Windows - Run Process ping -n 5 -4 localhost stdout=ping_output.txt stderr=ping_error.txt + Run Process ping -n 5 -4 localhost stdout=ping_output.txt stderr=ping_error.txt ``` diff --git a/website/docs/chapter-02/06_writing_test.md b/website/docs/chapter-02/06_writing_test.md index 481173e4..7ebb4a97 100644 --- a/website/docs/chapter-02/06_writing_test.md +++ b/website/docs/chapter-02/06_writing_test.md @@ -37,22 +37,28 @@ Mixed Positional Arguments ... ... It is hard to figure out what the values are doing and which arguments are filled, ... without looking into the keyword documentation. - ... Even though the argument `values` is kept at its default value `True` it must be set if later arguments shall be set positionally. + ... Even though the argument `values` is kept at its default value `True`, + ... it must be set if later arguments shall be set positionally. Should Be Equal hello HELLO Values are case-insensitive NOT equal True True All Named Arguments [Documentation] Arguments are used named. ... - ... It is clear what the values are doing and which arguments are filled and order is not relevant. + ... It is clear what the values are doing and which arguments are filled + ... and order is not relevant. ... The argument `values` can be omitted and the order can be mixed - Should Be Equal first=hello second=HELLO ignore_case=True msg=Values are case-insensitive NOT equal + Should Be Equal first=hello second=HELLO + ... ignore_case=True msg=Values are case-insensitive NOT equal Mixed Named and Positional Arguments [Documentation] Arguments are used named and positional. ... - ... The positional arguments must be in order, but the subsequent named arguments may be in an arbitrary order. - ... The first arg has the string value `" hello spaces "` and the second arg has the string value `"HELLO SPACE"`. - Should Be Equal \ hello \ spaces \ HELLO \ SPACE ignore_case=True strip_spaces=True msg=Values are case-insensitive NOT equal + ... The positional arguments must be in order, + ... but the subsequent named arguments may be in an arbitrary order. + ... The first arg has the string value `" hello spaces "` + ... and the second arg has the string value `"HELLO SPACE"`. + Should Be Equal \ hello \ spaces \ HELLO \ SPACE + ... ignore_case=True strip_spaces=True msg=Values are case-insensitive NOT equal ``` diff --git a/website/docs/chapter-03/02_variables.md b/website/docs/chapter-03/02_variables.md index b63302c2..16e94e59 100644 --- a/website/docs/chapter-03/02_variables.md +++ b/website/docs/chapter-03/02_variables.md @@ -180,10 +180,8 @@ ${SEARCH_URL} https://example.com/search ... separator= ``` -`${SEARCH_URL}` will contain: -``` -https://example.com/search?query=robot+framework&page=1&filter=recent&lang=en&category=test-automation -``` +`${SEARCH_URL}` will contain the following without any spaces or newlines: +`https://example.com/search?query=robot+framework&page=1&filter=recent&lang=en&category=test-automation` ### 3.2.2.2 Primitive Data Types diff --git a/website/docs/chapter-03/03_user_keyword.md b/website/docs/chapter-03/03_user_keyword.md index f4adc737..2e5e5d87 100644 --- a/website/docs/chapter-03/03_user_keyword.md +++ b/website/docs/chapter-03/03_user_keyword.md @@ -95,7 +95,7 @@ All available settings are listed below and explained in this section or in sect - `[Setup]`, `[Teardown]` Specify user keyword setup and teardown. (see [4.2 Teardowns (Suite, Test|Task, Keyword)](chapter-04/02_teardowns.md)) - `[Tags]` (*) Sets tags for the keyword, which can be used for filtering in documentation and attribution for post-processing results. - `[Timeout]` (*) Sets the possible user keyword timeout. -- `[Return]` (*) Deprecated. +- `[Return]` (*) Deprecated. Use the `RETURN` statement instead. (see [3.3.6 RETURN Statement](chapter-03/03_user_keyword.md#336-return-statement)) (*) The application of these settings are not part of this syllabus. @@ -190,7 +190,8 @@ Example that defines a keyword with two arguments: Verify File Contains [Documentation] Verifies that a file contains a specific text. ... - ... The keyword opens the file specified by the file path and checks if it contains the expected content. + ... The keyword opens the file specified by the file path + ... and checks if it contains the expected content. [Arguments] ${file_path} ${expected_content} ${server_log} = Get File ${file_path} Should Contain ${server_log} ${expected_content} diff --git a/website/docs/chapter-03/05_advanced_importing.md b/website/docs/chapter-03/05_advanced_importing.md index 783d6a4b..be27581e 100644 --- a/website/docs/chapter-03/05_advanced_importing.md +++ b/website/docs/chapter-03/05_advanced_importing.md @@ -111,7 +111,8 @@ These arguments follow the Library path or name, separated by multiple spaces. Example with the [Telnet library](https://robotframework.org/robotframework/latest/libraries/Telnet.html#Importing): ```robotframework *** Settings *** -Library Telnet newline=LF encoding=ISO-8859-1 # set newline and encoding using named arguments +Library Telnet newline=LF encoding=ISO-8859-1 +# ^ set newline and encoding using named arguments ``` Another example that cannot be used without configuration is the Remote library. @@ -159,7 +160,7 @@ Keywords like `Open Connection`, `Login`, `Read`, `Close Connection`, and many m These conflicts cannot be resolved by Robot Framework if they are coming from the same kind of source, like two libraries. The error message will be like this: -```plaintext +```plaintext nolint Multiple keywords with name 'Open Connection' found. Give the full name of the keyword you want to use: SSHLibrary.Open Connection Telnet.Open Connection diff --git a/website/docs/chapter-05/01_advanced_variables.md b/website/docs/chapter-05/01_advanced_variables.md index 9638582e..133198ba 100644 --- a/website/docs/chapter-05/01_advanced_variables.md +++ b/website/docs/chapter-05/01_advanced_variables.md @@ -331,9 +331,9 @@ Example: *** Test Cases *** Test List Variables - Log Many Alice Bob Charlie # Logs three entries: "Alice", "Bob", and "Charlie" - Log Many @{participants} # Logs three entries: "Alice", "Bob", and "Charlie" - Log Many ${participants} # Logs only one entry: "['Alice', 'Bob', 'Charlie']" + Log Many Alice Bob Charlie # Logs three entries: "Alice", "Bob", and "Charlie" + Log Many @{participants} # Logs three entries: "Alice", "Bob", and "Charlie" + Log Many ${participants} # Logs only one entry: "['Alice', 'Bob', 'Charlie']" ``` In the first two cases, the keyword `Log Many` is called with three arguments; in the last case, it is called with only one argument, which is a list of three values. @@ -367,8 +367,8 @@ Example: ```robotframework *** Test Cases *** Test Dictionary Variables - &{participant} Get Participant number=4 # returns a dictionary with keys "name" and "age" - ${trainer} Get Trainer number=1 # returns a dictionary with keys "name" and "age" + &{participant} Get Participant number=4 # returns a dictionary with keys "name" and "age" + ${trainer} Get Trainer number=1 # returns a dictionary with keys "name" and "age" ``` In the following example, the first assignment to `&{participant}` causes an automatic conversion to a Robot Framework Dictionary, also known as DotDict. These special dictionary types can be accessed using dot-access like `${participant.name}` or `${participant.age}`, instead of the usual dictionary access like `${trainer}[name]` or `${trainer}[age]`. diff --git a/website/docs/chapter-05/02_control_structures.md b/website/docs/chapter-05/02_control_structures.md index 2b5e701c..8d660524 100644 --- a/website/docs/chapter-05/02_control_structures.md +++ b/website/docs/chapter-05/02_control_structures.md @@ -285,11 +285,16 @@ Find Older Participants *** Keywords *** Get Older Participants [Arguments] ${participants} ${minimum_age} - VAR @{older_participants} # Creates an empty list - FOR ${participant} IN @{participants} # Iterates over all participants - IF ${participant.age} < ${minimum_age} CONTINUE # Skips the remaining part of the loop if age is below the minimum - Log Participant ${participant.name} is older than 40 # Logs participant name if age is above the minimum - Append To List ${older_participants} ${participant} # BuiltIn keyword to append a value to a list + VAR @{older_participants} + # ^ Creates an empty list + FOR ${participant} IN @{participants} + # ^ Iterates over all participants + IF ${participant.age} < ${minimum_age} CONTINUE + # ^ Skips the remaining part of the loop if age is below the minimum + Log Participant ${participant.name} is older than 40 + # ^ Logs participant name if age is above the minimum + Append To List ${older_participants} ${participant} + # ^ BuiltIn keyword to append a value to a list END RETURN ${older_participants} ``` diff --git a/website/docs/learning_objectives.md b/website/docs/learning_objectives.md index 5abf7790..b5d60120 100644 --- a/website/docs/learning_objectives.md +++ b/website/docs/learning_objectives.md @@ -110,7 +110,7 @@ | [`LO-4.2.2-1`](chapter-04/02_teardowns.md#422-testtask-teardown) | K1 | Recall key characteristics, benefits, and syntax of Test\|Task Teardown | | [`LO-4.2.2-2`](chapter-04/02_teardowns.md#422-testtask-teardown) | K2 | Understand when Test\|Task Teardown is executed and used | | [`LO-4.2.3`](chapter-04/02_teardowns.md#423-keyword-teardown) | K1 | Recall key characteristics, benefits, and syntax of Keyword Teardown | -| [`LO-4.3`](chapter-04/03_init_files.md) | K1 | Recall how to define an Initialization Files and its purpose | +| [`LO-4.3`](chapter-04/03_init_files.md) | K1 | Recall how to define Initialization Files and its purpose | | [`LO-4.3.2`](chapter-04/03_init_files.md#432-suite-setup-and-suite-teardown-of-initialization-files) | K2 | Understand the execution order of Suite Setup and Suite Teardown in Initialization Files and their sub-suites and tests\|tasks | | [`LO-4.3.3`](chapter-04/03_init_files.md#433-allowed-sections-in-initialization-files) | K1 | Recall the allowed sections and their content in Initialization Files | | [`LO-4.4`](chapter-04/04_tags.md) | K1 | Recall the purpose of Test\|Task Tags in Robot Framework | diff --git a/website/docusaurus.config.ts b/website/docusaurus.config.ts index f37dcaa4..0e01ee51 100644 --- a/website/docusaurus.config.ts +++ b/website/docusaurus.config.ts @@ -5,6 +5,8 @@ const lightCodeTheme = require('prism-react-renderer').themes.vsLight; const darkCodeTheme = require('prism-react-renderer').themes.dracula; import remarkDirective from "remark-directive"; import remarkTermDirective from "./src/remark/remark-term-directive.js"; +import codeMaxLineLength from './src/remark/remark-code-max-line-length.js'; + /** @type {import('@docusaurus/types').Config} */ const config = { @@ -36,7 +38,7 @@ const config = { sidebarPath: require.resolve('./sidebars.js'), // Please change this to your repo. // editUrl: 'https://github.com/robotframework/robotframework-RFCP-syllabus/edit/docusaurus/website', - remarkPlugins: [remarkDirective, remarkTermDirective], + remarkPlugins: [remarkDirective, remarkTermDirective, [codeMaxLineLength, { max: 100 }]], }, blog: false, theme: { diff --git a/website/src/components/Quiz/quizComponents.ts b/website/src/components/Quiz/quizComponents.ts index 4c50d856..21b28d09 100644 --- a/website/src/components/Quiz/quizComponents.ts +++ b/website/src/components/Quiz/quizComponents.ts @@ -1,6 +1,6 @@ /* * This file is automatically generated and will be overridden when running the build process. -* Generated on: 11/22/2025, 2:34:08 PM +* Generated on: 12/5/2025, 1:04:36 PM */ export interface QuizPage { diff --git a/website/src/remark/remark-code-max-line-length.js b/website/src/remark/remark-code-max-line-length.js new file mode 100644 index 00000000..700f7c92 --- /dev/null +++ b/website/src/remark/remark-code-max-line-length.js @@ -0,0 +1,34 @@ +// plugins/remark-code-max-line-length.js +import {visit} from 'unist-util-visit'; + +/** + * @param {{ max?: number }} options + */ +export default function codeMaxLineLength(options = {}) { + const max = options.max ?? 100; + + return (tree, file) => { + visit(tree, 'code', (node) => { + // Optional: allow opt-out with "nolint" in code block meta: + // ```js nolint + if (node.meta && node.meta.includes('nolint')) { + return; + } + + const lines = node.value.split('\n'); + const blockStartLine = node.position?.start?.line ?? 1; + + lines.forEach((line, idx) => { + if (line.length > max) { + const lineNumber = blockStartLine + idx + 1; + const column = Math.min(line.length, max) + 1; + file.fail( + `Code block line ${lineNumber} exceeds max length ${max} (got ${line.length})`, + {line: lineNumber, column}, + 'remark-code-max-line-length' + ); + } + }); + }); + }; +}