From 3c25a415468d210b49f331a59b8fb274eaac4461 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rene=CC=81?= Date: Fri, 5 Dec 2025 20:10:29 +0100 Subject: [PATCH 01/12] implemented dynamic glossary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: René --- Glossary_wip.md | 27 ---------------------- website/docs/glossary/Glossary.md | 27 ---------------------- website/package-lock.json | 31 ++++++++++++++++++++++---- website/package.json | 4 +++- website/src/theme/Admonition/index.tsx | 3 ++- website/tsconfig.json | 3 ++- 6 files changed, 34 insertions(+), 61 deletions(-) delete mode 100644 Glossary_wip.md delete mode 100644 website/docs/glossary/Glossary.md diff --git a/Glossary_wip.md b/Glossary_wip.md deleted file mode 100644 index fec4da9..0000000 --- a/Glossary_wip.md +++ /dev/null @@ -1,27 +0,0 @@ -# Glossary - -| Term | Definition | -| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| **Behavior-Driven** | A testing methodology that encourages collaboration between developers, QA, and non-technical stakeholders to define test cases. | -| **Data-Driven Specification** | A testing approach where test cases are executed with multiple sets of data to validate functionality. | -| **Generic Test Automation Architecture (gTAA)** | A framework that provides a structured approach to test automation, promoting reusability and maintainability. | -| **Keywords** | Reusable functions or actions defined in the test automation framework. | -| **Keyword-Driven** | A testing approach where test cases are defined using keywords that represent actions or operations. | -| **Library** | A collection of keywords and functions that can be used in test automation. | -| **Libdoc** | A tool used to generate keyword documentation for libraries and resource files. | -| **Rebot** | The main executable used to execute suites and post-process execution results to generate reports. | -| **Resource Files** | Files that contain shared keywords and variables that can be imported into test suites. | -| **Root Suite** | The top-level suite that contains all other suites and test cases. | -| **Suite Directory** | A directory that contains multiple suite files, which can include test cases and tasks organized hierarchically. | -| **Suite File** | A \*.robot file that contains at least one test case or task. | -| **Task** | A unit of work that can be executed, similar to a test case but typically focused on automation tasks. | -| **Task Suite** | Suite files that have at least one task and do not contain any test cases. | -| **Test Automation** | The use of software tools to execute tests automatically, reducing manual effort. | -| **Test Cases Section** | This section defines the executable elements of a suite, specifically test cases. | -| **Test Suite** | Suite files that have at least one test case and do not contain any tasks. | -| **Tasks Section** | This section defines the executable elements of a suite, specifically tasks. | -| **Comments Section** | This section is used to add comments to the suite file or resource file. All content in this section is ignored by Robot Framework. | -| **Keyword Section** | This section allows you to define locally scoped user keywords that can only be used within the same suite where they are defined. | -| **Robot Framework Sections** | Different parts of a Robot Framework suite file that organize the content. | -| **Settings Section** | This section is used to configure various aspects of the test/task suite. | -| **Variables Section** | This section is used to define suite variables that are used in the suite or its tests/tasks or inside their keywords. | diff --git a/website/docs/glossary/Glossary.md b/website/docs/glossary/Glossary.md deleted file mode 100644 index fec4da9..0000000 --- a/website/docs/glossary/Glossary.md +++ /dev/null @@ -1,27 +0,0 @@ -# Glossary - -| Term | Definition | -| ----------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------- | -| **Behavior-Driven** | A testing methodology that encourages collaboration between developers, QA, and non-technical stakeholders to define test cases. | -| **Data-Driven Specification** | A testing approach where test cases are executed with multiple sets of data to validate functionality. | -| **Generic Test Automation Architecture (gTAA)** | A framework that provides a structured approach to test automation, promoting reusability and maintainability. | -| **Keywords** | Reusable functions or actions defined in the test automation framework. | -| **Keyword-Driven** | A testing approach where test cases are defined using keywords that represent actions or operations. | -| **Library** | A collection of keywords and functions that can be used in test automation. | -| **Libdoc** | A tool used to generate keyword documentation for libraries and resource files. | -| **Rebot** | The main executable used to execute suites and post-process execution results to generate reports. | -| **Resource Files** | Files that contain shared keywords and variables that can be imported into test suites. | -| **Root Suite** | The top-level suite that contains all other suites and test cases. | -| **Suite Directory** | A directory that contains multiple suite files, which can include test cases and tasks organized hierarchically. | -| **Suite File** | A \*.robot file that contains at least one test case or task. | -| **Task** | A unit of work that can be executed, similar to a test case but typically focused on automation tasks. | -| **Task Suite** | Suite files that have at least one task and do not contain any test cases. | -| **Test Automation** | The use of software tools to execute tests automatically, reducing manual effort. | -| **Test Cases Section** | This section defines the executable elements of a suite, specifically test cases. | -| **Test Suite** | Suite files that have at least one test case and do not contain any tasks. | -| **Tasks Section** | This section defines the executable elements of a suite, specifically tasks. | -| **Comments Section** | This section is used to add comments to the suite file or resource file. All content in this section is ignored by Robot Framework. | -| **Keyword Section** | This section allows you to define locally scoped user keywords that can only be used within the same suite where they are defined. | -| **Robot Framework Sections** | Different parts of a Robot Framework suite file that organize the content. | -| **Settings Section** | This section is used to configure various aspects of the test/task suite. | -| **Variables Section** | This section is used to define suite variables that are used in the suite or its tests/tasks or inside their keywords. | diff --git a/website/package-lock.json b/website/package-lock.json index 29f4a7c..aa068bc 100644 --- a/website/package-lock.json +++ b/website/package-lock.json @@ -16,6 +16,8 @@ "clsx": "^2.1.1", "docusaurus-lunr-search": "^3.6.0", "dompurify": "^3.3.0", + "fuse.js": "^7.1.0", + "marked": "^12.0.2", "prism-react-renderer": "^2.4.1", "quizdown-extended": "^1.2.1", "react": "^19.2.0", @@ -3345,6 +3347,18 @@ } } }, + "node_modules/@docsearch/react/node_modules/marked": { + "version": "16.4.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-16.4.2.tgz", + "integrity": "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==", + "license": "MIT", + "bin": { + "marked": "bin/marked.js" + }, + "engines": { + "node": ">= 20" + } + }, "node_modules/@docusaurus/babel": { "version": "3.9.2", "resolved": "https://registry.npmjs.org/@docusaurus/babel/-/babel-3.9.2.tgz", @@ -9561,6 +9575,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/fuse.js": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-7.1.0.tgz", + "integrity": "sha512-trLf4SzuuUxfusZADLINj+dE8clK1frKdmqiJNb1Es75fmI5oY6X2mxLVUciLLjxqw/xr72Dhy+lER6dGd02FQ==", + "license": "Apache-2.0", + "engines": { + "node": ">=10" + } + }, "node_modules/gauge": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/gauge/-/gauge-3.0.2.tgz", @@ -11919,15 +11942,15 @@ } }, "node_modules/marked": { - "version": "16.4.2", - "resolved": "https://registry.npmjs.org/marked/-/marked-16.4.2.tgz", - "integrity": "sha512-TI3V8YYWvkVf3KJe1dRkpnjs68JUPyEa5vjKrp1XEEJUAOaQc+Qj+L1qWbPd0SJuAdQkFU0h73sXXqwDYxsiDA==", + "version": "12.0.2", + "resolved": "https://registry.npmjs.org/marked/-/marked-12.0.2.tgz", + "integrity": "sha512-qXUm7e/YKFoqFPYPa3Ukg9xlI5cyAtGmyEIzMfW//m6kXwCy2Ps9DYf5ioijFKQ8qyuscrHoY04iJGctu2Kg0Q==", "license": "MIT", "bin": { "marked": "bin/marked.js" }, "engines": { - "node": ">= 20" + "node": ">= 18" } }, "node_modules/math-intrinsics": { diff --git a/website/package.json b/website/package.json index 4494891..1559bd9 100644 --- a/website/package.json +++ b/website/package.json @@ -26,9 +26,11 @@ "clsx": "^2.1.1", "docusaurus-lunr-search": "^3.6.0", "dompurify": "^3.3.0", + "fuse.js": "^7.1.0", + "marked": "^12.0.2", + "prism-react-renderer": "^2.4.1", "quizdown-extended": "^1.2.1", "react": "^19.2.0", - "prism-react-renderer": "^2.4.1", "react-dom": "^19.2.0", "react-markdown": "^10.1.0", "rehype-raw": "^7.0.0", diff --git a/website/src/theme/Admonition/index.tsx b/website/src/theme/Admonition/index.tsx index d524a6d..f589cb3 100644 --- a/website/src/theme/Admonition/index.tsx +++ b/website/src/theme/Admonition/index.tsx @@ -6,9 +6,10 @@ import K2Icon from '@site/static/img/K2.svg'; import K3Icon from '@site/static/img/K3.svg'; import type AdmonitionType from '@theme/Admonition'; +import type {AdmonitionProps} from '@theme/Admonition'; import type {WrapperProps} from '@docusaurus/types'; -type Props = WrapperProps; +type Props = WrapperProps & AdmonitionProps; export default function AdmonitionWrapper(props: Props): ReactNode { if (props.type === 'lo') { diff --git a/website/tsconfig.json b/website/tsconfig.json index 920d7a6..f5ec699 100644 --- a/website/tsconfig.json +++ b/website/tsconfig.json @@ -2,7 +2,8 @@ // This file is not used in compilation. It is here just for a nice editor experience. "extends": "@docusaurus/tsconfig", "compilerOptions": { - "baseUrl": "." + "baseUrl": ".", + "types": ["@docusaurus/module-type-aliases"] }, "exclude": [".docusaurus", "build"] } From dbb34ac8bcfd840f9dea56ddac02804588e4a112 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rene=CC=81?= Date: Fri, 5 Dec 2025 20:11:09 +0100 Subject: [PATCH 02/12] implemented dynamic glossary MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: René --- website/docs/glossary/Glossary.mdx | 10 + .../Glossary/GlossaryTable.module.css | 151 ++++++ .../src/components/Glossary/GlossaryTable.tsx | 277 +++++++++++ website/src/types/docusaurus-theme.d.ts | 43 ++ website/static/glossary/glossary.json | 446 ++++++++++++++++++ 5 files changed, 927 insertions(+) create mode 100644 website/docs/glossary/Glossary.mdx create mode 100644 website/src/components/Glossary/GlossaryTable.module.css create mode 100644 website/src/components/Glossary/GlossaryTable.tsx create mode 100644 website/src/types/docusaurus-theme.d.ts create mode 100644 website/static/glossary/glossary.json diff --git a/website/docs/glossary/Glossary.mdx b/website/docs/glossary/Glossary.mdx new file mode 100644 index 0000000..ced04b9 --- /dev/null +++ b/website/docs/glossary/Glossary.mdx @@ -0,0 +1,10 @@ +--- +id: interactive-glossary +title: Interactive Glossary +--- + +import GlossaryTable from '@site/src/components/Glossary/GlossaryTable'; + +Use the search boxes to filter by term or perform a fuzzy free-text search across definitions. Click any row or alias to deep-link to a glossary entry. + + diff --git a/website/src/components/Glossary/GlossaryTable.module.css b/website/src/components/Glossary/GlossaryTable.module.css new file mode 100644 index 0000000..4016e6f --- /dev/null +++ b/website/src/components/Glossary/GlossaryTable.module.css @@ -0,0 +1,151 @@ +.wrapper { + margin: 1.5rem 0; + display: flex; + flex-direction: column; + gap: 1rem; +} + +.controls { + display: grid; + gap: 0.75rem; + grid-template-columns: repeat(auto-fit, minmax(240px, 1fr)); +} + +.control { + display: flex; + flex-direction: column; + gap: 0.35rem; + font-weight: 600; + color: var(--ifm-color-primary); +} + +.control input { + padding: 0.5rem 0.75rem; + border-radius: 0.35rem; + border: 1px solid var(--ifm-color-emphasis-300); + background: var(--ifm-background-color); + color: var(--ifm-font-color-base); +} + +.tableWrapper { + overflow-x: auto; + border: 1px solid var(--ifm-color-emphasis-200); + border-radius: 0.5rem; +} + +.table { + width: 100%; + border-collapse: collapse; + table-layout: fixed; +} + +.termCol { + width: 28%; +} + +.definitionCol { + width: 72%; +} + +th, +td { + padding: 0.85rem 1rem; + text-align: left; + vertical-align: top; +} + +th { + background: var(--ifm-color-emphasis-100); + font-size: 0.95rem; + letter-spacing: 0.01em; +} + +tr:nth-child(even) { + background: var(--ifm-table-stripe-background); +} + +tbody tr { + scroll-margin-top: 72px; /* leave space for sticky header */ +} + +.activeRow { + outline: 2px solid var(--ifm-color-primary); + outline-offset: -2px; + background: var(--ifm-color-emphasis-100); +} + +.termCell { + min-width: 180px; + font-weight: 700; +} + +.clickable { + cursor: pointer; +} + +.termName { + margin-bottom: 0.25rem; +} + +.definitionCell { + width: 100%; +} + +.emptyState { + text-align: center; + padding: 1rem; + color: var(--ifm-color-emphasis-700); +} + +.definitionText > :first-child { + margin-top: 0; +} + +.definitionText > :last-child { + margin-bottom: 0; +} + +.pillRow { + display: flex; + gap: 0.4rem; + flex-wrap: wrap; + margin-top: 0.5rem; +} + +.pill { + display: inline-flex; + align-items: center; + gap: 0.25rem; + padding: 0.15rem 0.6rem; + border-radius: 999px; + font-size: 0.8rem; + border: 1px solid var(--ifm-color-emphasis-300); + background: var(--ifm-color-emphasis-100); + color: var(--ifm-font-color-base); + text-decoration: none; +} + +.pill:hover, +.pill:focus-visible { + border-color: var(--ifm-color-primary); + color: var(--ifm-color-primary); +} + +.abbreviationPill { + font-weight: 700; +} + +.aliasPill { + font-weight: 600; +} + +.aliasLink { + color: var(--ifm-color-primary); + text-decoration: underline; + font-weight: 600; +} + +.aliasLink:hover, +.aliasLink:focus-visible { + color: var(--ifm-color-primary-darker); +} diff --git a/website/src/components/Glossary/GlossaryTable.tsx b/website/src/components/Glossary/GlossaryTable.tsx new file mode 100644 index 0000000..4b671e6 --- /dev/null +++ b/website/src/components/Glossary/GlossaryTable.tsx @@ -0,0 +1,277 @@ +import React, { useCallback, useEffect, useMemo, useState } from 'react'; +import Fuse from 'fuse.js'; +import clsx from 'clsx'; +import { marked } from 'marked'; +import DOMPurify from 'dompurify'; +import glossaryData from '@site/static/glossary/glossary.json'; +import styles from './GlossaryTable.module.css'; + +export type GlossaryItem = { + term: string; + aliasses: string[]; + abbreviation: string; + definition: string; +}; + +export type DisplayEntry = { + term: string; + abbreviation: string; + definition: string; + canonicalTerm: string; + isAlias: boolean; + slug: string; + targetSlug: string; + aliases: string[]; +}; + +const slugify = (text: string): string => + text + .toLowerCase() + .replace(/[^a-z0-9]+/g, '-') + .replace(/(^-+|-+$)/g, ''); + +const sanitizeMarkdown = (markdown: string, purify: typeof DOMPurify | null): string => { + const html = marked.parse(markdown || '', { async: false }) as string; + return purify ? purify.sanitize(html) : html; +}; + +const GlossaryTable: React.FC = () => { + const [termQuery, setTermQuery] = useState(''); + const [textQuery, setTextQuery] = useState(''); + const [activeSlug, setActiveSlug] = useState(''); + + const purify = useMemo(() => (typeof window === 'undefined' ? null : DOMPurify), []); + + const { entries, aliasToCanonicalSlug } = useMemo(() => { + const glossaryItems = glossaryData as GlossaryItem[]; + const termSet = new Set(glossaryItems.map((item) => item.term)); + + const canonicalEntries: DisplayEntry[] = glossaryItems.map((item) => { + const slug = slugify(item.term); + return { + term: item.term, + abbreviation: item.abbreviation, + definition: item.definition, + canonicalTerm: item.term, + isAlias: false, + slug, + targetSlug: slug, + aliases: item.aliasses || [], + }; + }); + + const aliasEntries: DisplayEntry[] = glossaryItems.flatMap((item) => { + const canonicalSlug = slugify(item.term); + return (item.aliasses || []) + .filter((alias) => !termSet.has(alias)) + .map((alias) => ({ + term: alias, + abbreviation: '', + definition: `See ${item.term}`, + canonicalTerm: item.term, + isAlias: true, + slug: slugify(alias), + targetSlug: canonicalSlug, + aliases: [], + })); + }); + + const aliasMap = new Map(); + canonicalEntries.forEach((entry) => aliasMap.set(entry.slug, entry.targetSlug)); + aliasEntries.forEach((entry) => aliasMap.set(entry.slug, entry.targetSlug)); + + const combined = [...canonicalEntries, ...aliasEntries].sort((a, b) => a.term.localeCompare(b.term)); + return { entries: combined, aliasToCanonicalSlug: aliasMap }; + }, []); + + const fuse = useMemo( + () => + new Fuse(entries, { + keys: [ + { name: 'term', weight: 0.5 }, + { name: 'definition', weight: 0.4 }, + { name: 'abbreviation', weight: 0.1 }, + { name: 'aliases', weight: 0.3 }, + ], + threshold: 0.35, + ignoreLocation: true, + }), + [entries] + ); + + const focusEntry = useCallback( + (slug: string, canonicalTerm?: string) => { + if (!slug || typeof window === 'undefined') { + return; + } + + const targetSlug = slug; + setActiveSlug(targetSlug); + + const url = new URL(window.location.href); + url.hash = targetSlug; + if (canonicalTerm) { + url.searchParams.set('term', canonicalTerm); + } else { + url.searchParams.set('term', targetSlug); + } + window.history.replaceState({}, '', url.toString()); + + const target = document.getElementById(targetSlug); + if (target) { + const top = target.getBoundingClientRect().top + window.scrollY - 70; // account for sticky header + window.scrollTo({ top, behavior: 'smooth' }); + } + }, + [aliasToCanonicalSlug] + ); + + useEffect(() => { + if (typeof window === 'undefined') { + return; + } + + const params = new URLSearchParams(window.location.search); + const termParam = params.get('term'); + const hashParam = window.location.hash ? window.location.hash.replace('#', '') : ''; + const rawSlug = hashParam || (termParam ? slugify(termParam) : ''); + const initialSlug = aliasToCanonicalSlug.get(rawSlug) || rawSlug; + + if (initialSlug) { + setActiveSlug(initialSlug); + // Allow the page to render before scrolling + setTimeout(() => focusEntry(initialSlug, termParam || initialSlug), 50); + } + }, [aliasToCanonicalSlug, focusEntry]); + + const filteredEntries = useMemo(() => { + const normalize = (value: string) => value.toLowerCase(); + let subset = entries; + + if (termQuery.trim()) { + const query = normalize(termQuery.trim()); + subset = subset.filter((entry) => { + return ( + normalize(entry.term).includes(query) || + normalize(entry.canonicalTerm).includes(query) || + (entry.aliases || []).some((alias) => normalize(alias).includes(query)) + ); + }); + } + + if (textQuery.trim()) { + const results = fuse.search(textQuery.trim()); + const allowedSlugs = new Set(); + results.forEach(({ item }) => allowedSlugs.add(item.slug)); + subset = subset.filter((entry) => allowedSlugs.has(entry.slug)); + } + + return subset; + }, [entries, fuse, termQuery, textQuery]); + + return ( +
+
+ + +
+ +
+ + + + + + + + + {filteredEntries.map((entry) => { + const definitionHtml = sanitizeMarkdown(entry.definition, purify); + const handleClick = () => focusEntry(entry.targetSlug, entry.canonicalTerm); + + return ( + + + + + ); + })} + +
TermDefinition & Abbreviation
+
{entry.term}
+
+ {entry.isAlias ? ( + // Hyperlink to term in alias definition cell + { + event.preventDefault(); + event.stopPropagation(); + focusEntry(entry.targetSlug, entry.canonicalTerm); + }} + > + See {entry.canonicalTerm} + + ) : ( + <> +
+
+ {entry.abbreviation ? ( + + {entry.abbreviation} + + ) : null} + {(entry.aliases || []).map((alias) => { + const aliasSlug = slugify(alias); + const target = aliasToCanonicalSlug.get(aliasSlug) || aliasSlug; + return ( + // Link to alias term + { + event.preventDefault(); + event.stopPropagation(); + focusEntry(aliasSlug, alias); + }} + > + {alias} + + ); + })} +
+ + )} +
+
+
+ ); +}; + +export default GlossaryTable; diff --git a/website/src/types/docusaurus-theme.d.ts b/website/src/types/docusaurus-theme.d.ts new file mode 100644 index 0000000..0c2050a --- /dev/null +++ b/website/src/types/docusaurus-theme.d.ts @@ -0,0 +1,43 @@ +declare module '@theme/Heading' { + import type {ComponentType, ReactNode, ElementType} from 'react'; + + type HeadingProps = { + as?: ElementType; + className?: string; + id?: string; + children?: ReactNode; + }; + + const Heading: ComponentType; + export default Heading; +} + +declare module '@theme/Admonition' { + import type {ComponentType, ReactNode} from 'react'; + + export type AdmonitionProps = { + readonly type?: string; + readonly title?: ReactNode; + readonly icon?: ReactNode; + children?: ReactNode; + }; + + const Admonition: ComponentType; + export default Admonition; +} + +declare module '@theme/Layout' { + import type {ComponentType, ReactNode} from 'react'; + + export interface Props { + children?: ReactNode; + title?: string; + description?: string; + wrapperClassName?: string; + noFooter?: boolean; + noNavbar?: boolean; + } + + const Layout: ComponentType; + export default Layout; +} diff --git a/website/static/glossary/glossary.json b/website/static/glossary/glossary.json new file mode 100644 index 0000000..6064494 --- /dev/null +++ b/website/static/glossary/glossary.json @@ -0,0 +1,446 @@ +[ + { + "term": "Acceptance Testing", + "aliasses": [], + "abbreviation": "", + "definition": "Testing that validates whether a system meets business requirements and is ready for deployment or release, often defined or reviewed by business stakeholders." + }, + { + "term": "Adaptation Layer", + "aliasses": [], + "abbreviation": "", + "definition": "The layer in the Generic Test Automation Architecture (gTAA) that connects Robot Framework to the System Under Test or automated systems via keyword libraries." + }, + { + "term": "Atomic Element", + "aliasses": [], + "abbreviation": "", + "definition": "An execution element such as a library keyword or Robot Framework language statement that does not contain child steps; its status is determined only by its own execution result." + }, + { + "term": "Automation Script", + "aliasses": [], + "abbreviation": "", + "definition": "A Robot Framework suite, test, task, or keyword collection that automates a defined workflow or behavior." + }, + { + "term": "Argument", + "aliasses": [], + "abbreviation": "", + "definition": "A value passed to a keyword when it is called to customize its behavior. Arguments can have different kinds (for example positional, named, embedded) and may be mandatory or optional." + }, + { + "term": "Argument Interface", + "aliasses": [], + "abbreviation": "", + "definition": "The complete, ordered list of arguments that a keyword accepts, including their names, kinds, default values and optional type hints, as shown in keyword documentation." + }, + { + "term": "Behavior-Driven Development", + "aliasses": [], + "abbreviation": "BDD", + "definition": "A development approach and collaboration practice that describes system behavior in business-readable language, often using Given/When/Then phrasing." + }, + { + "term": "Behavior-Driven Specification", + "aliasses": [], + "abbreviation": "", + "definition": "A declarative specification style in Robot Framework where tests|tasks describe system behavior from the user’s perspective, typically using natural-language-like steps with embedded arguments and prefixes such as Given/When/Then/And/But." + }, + { + "term": "Built-In Variables", + "aliasses": [], + "abbreviation": "", + "definition": "Special variables provided by Robot Framework that expose execution-related information such as paths, timestamps, and status without needing explicit definition." + }, + { + "term": "Command Line Interface", + "aliasses": ["Robot Framework CLI"], + "abbreviation": "CLI", + "definition": "The interface used to run Robot Framework from the command line (e.g. with the `robot` command), configure execution options, and pass arguments or variables." + }, + { + "term": "Composite Element", + "aliasses": [], + "abbreviation": "", + "definition": "An execution element that is composed of other elements (for example a suite composed of tests|tasks, a test|task composed of keywords, or a user keyword composed of child keywords and statements) and whose status is derived from its children." + }, + { + "term": "Control Structure", + "aliasses": [], + "abbreviation": "", + "definition": "Statements like IF, FOR, WHILE, BREAK and CONTINUE used in Robot Framework to control the execution flow inside a test, task or keyword." + }, + { + "term": "Data-Driven Specification", + "aliasses": [], + "abbreviation": "", + "definition": "A style where the same logic or test flow is executed multiple times with different input and/or expected output data, often implemented using test|task templates in Robot Framework." + }, + { + "term": "Definition Layer", + "aliasses": [], + "abbreviation": "", + "definition": "The layer in the Generic Test Automation Architecture (gTAA) containing the test data, such as suites, tests, tasks, resource files, keywords, and variables written in Robot Framework syntax." + }, + { + "term": "Embedded Argument", + "aliasses": [], + "abbreviation": "", + "definition": "An argument whose value is part of the keyword name text itself, typically used in behavior-driven style steps like `Given \"robotframework.org\" is open`." + }, + { + "term": "End-to-End Test", + "aliasses": [], + "abbreviation": "", + "definition": "Tests that verifies complete workflows across all relevant components, subsystems and interfaces to ensure that real-world user flows behave as expected." + }, + { + "term": "Execution Artifacts", + "aliasses": [], + "abbreviation": "", + "definition": "Files and outputs generated by Robot Framework execution, such as `output.xml`, `log.html`, and `report.html`, which document what was executed and with which results." + }, + { + "term": "Execution Layer", + "aliasses": [], + "abbreviation": "", + "definition": "The layer in the Generic Test Automation Architecture (gTAA) that includes Robot Framework’s parser, execution engine, logging, and reporting components which interpret test data and run keywords." + }, + { + "term": "Execution Model", + "aliasses": [], + "abbreviation": "", + "definition": "The internal representation created by Robot Framework after parsing suites, tests, tasks, and keywords, which the execution engine uses to perform automation." + }, + { + "term": "Fail Status", + "aliasses": [], + "abbreviation": "", + "definition": "An execution status indicating that an element (such as a keyword, test, task or suite) did not meet its expected outcome or raised an error during execution." + }, + { + "term": "FOR Loop", + "aliasses": [], + "abbreviation": "", + "definition": "A control structure in Robot Framework used to iterate over items in a list or other iterable and execute a body of keywords for each item." + }, + { + "term": "Generic Test Automation Architecture", + "aliasses": ["gTAA"], + "abbreviation": "gTAA", + "definition": "A layered reference architecture for test automation that defines separation into definition, execution, and adaptation layers; used to describe Robot Framework’s role in an automation solution." + }, + { + "term": "Given / When / Then / And / But", + "aliasses": [], + "abbreviation": "", + "definition": "Conventional prefixes used in behavior-driven specification style. Robot Framework can ignore these prefixes when matching keywords if the remaining part of the name matches a keyword." + }, + { + "term": "Global Variable", + "aliasses": [], + "abbreviation": "", + "definition": "A variable with global scope that can be accessed from all suites and keywords in a Robot Framework execution." + }, + { + "term": "Higher-Level Suite (Suite Directory)", + "aliasses": [], + "abbreviation": "", + "definition": "A directory that is treated as a suite because it (directly or indirectly) contains at least one suite file; it groups lower-level suites into a suite tree." + }, + { + "term": "Initialization File (__init__.robot)", + "aliasses": [], + "abbreviation": "", + "definition": "A suite file located in a directory that configures that directory as a suite and can define suite-level settings, variables, setups and teardowns for all contained suites." + }, + { + "term": "Inline Comment", + "aliasses": [], + "abbreviation": "", + "definition": "A comment written either at the very beginning, or at the end of a line in a Robot Framework file, separated by at least two spaces and starting with a # so that it is ignored by the interpreter." + }, + { + "term": "Inline IF", + "aliasses": [], + "abbreviation": "", + "definition": "A compact IF statement form on a single line (IF [args]) used to execute one keyword conditionally without an END." + }, + { + "term": "K-Level (Knowledge Level)", + "aliasses": [], + "abbreviation": "", + "definition": "A categorization of learning objectives based on Bloom’s Taxonomy: K1 (Remember), K2 (Understand), and K3 (Apply), indicating the expected depth of knowledge." + }, + { + "term": "Keyword", + "aliasses": [], + "abbreviation": "", + "definition": "A named, reusable action or sequence of actions in Robot Framework that can be called from tests, tasks or other keywords and may accept arguments and may return values." + }, + { + "term": "Keyword Interface", + "aliasses": [], + "abbreviation": "", + "definition": "The documented information of a keyword, including its name, arguments (with kinds and types), return values, documentation, and examples, as exposed for example by HTML documentation or IDEs." + }, + { + "term": "Keyword-Driven Specification", + "aliasses": [], + "abbreviation": "", + "definition": "An imperative specification style in Robot Framework where tests|tasks are written as sequences of keyword calls with arguments, focusing on what actions are executed and in which order." + }, + { + "term": "Keyword Library", + "aliasses": ["Library"], + "abbreviation": "", + "definition": "A collection of library keywords implemented typically in Python (or other languages) that Robot Framework imports to interact with external systems, perform computations or provide utility functions." + }, + { + "term": "List Variable", + "aliasses": [], + "abbreviation": "", + "definition": "A Robot Framework variable of list type, accessed with the @{} syntax, that can hold an ordered collection of values and can be unpacked when passed to keywords." + }, + { + "term": "Local Variable", + "aliasses": [], + "abbreviation": "", + "definition": "A variable whose scope is limited to a single keyword, test or task execution and is not visible outside of that body." + }, + { + "term": "Log File (log.html)", + "aliasses": [], + "abbreviation": "", + "definition": "A detailed HTML execution log generated by Robot Framework that shows keyword-level execution steps, arguments, messages and statuses." + }, + { + "term": "Metadata (Suite Metadata)", + "aliasses": [], + "abbreviation": "", + "definition": "Key–value information defined with the Metadata setting in a suite, used to document additional attributes such as author, version, or related requirements." + }, + { + "term": "Named Argument", + "aliasses": [], + "abbreviation": "", + "definition": "A keyword argument specified using its name followed by = and a value (for example timeout=10 seconds), allowing arguments to be provided in any order." + }, + { + "term": "Named-Only Argument", + "aliasses": [], + "abbreviation": "", + "definition": "A keyword argument that must be provided by name and cannot be given positionally." + }, + { + "term": "Output File (output.xml)", + "aliasses": [], + "abbreviation": "", + "definition": "The main machine-readable execution result file produced by Robot Framework, containing the full execution tree, messages, and statistics in XML format." + }, + { + "term": "Pass Status", + "aliasses": [], + "abbreviation": "", + "definition": "An execution status indicating that an element (such as a keyword, test, task or suite) executed successfully and its expectations were met." + }, + { + "term": "Positional Argument", + "aliasses": [], + "abbreviation": "", + "definition": "A keyword argument provided solely by its position in the argument list without naming it explicitly." + }, + { + "term": "Report File (report.html)", + "aliasses": [], + "abbreviation": "", + "definition": "A high-level HTML summary of a Robot Framework execution that focuses on statistics and overall pass/fail status of suites and tests|tasks." + }, + { + "term": "Resource File", + "aliasses": [], + "abbreviation": "", + "definition": "A file (commonly with extension .resource or .robot) that contains user keywords and variables and is imported by suites to share and reuse these artifacts." + }, + { + "term": "Return Statement (RETURN)", + "aliasses": [], + "abbreviation": "", + "definition": "A statement used in user keywords to return one or more values that can be assigned to variables in the calling context." + }, + { + "term": "Return Type Hint", + "aliasses": [], + "abbreviation": "", + "definition": "A documented indication of the type of value a keyword returns, helping users understand how to use the returned data." + }, + { + "term": "Robotic Process Automation", + "aliasses": ["RPA"], + "abbreviation": "RPA", + "definition": "Automation of business processes or tasks normally performed by humans, often across multiple systems, without necessarily focusing on testing." + }, + { + "term": "Robot Framework Foundation", + "aliasses": [], + "abbreviation": "", + "definition": "The non-profit association (Robot Framework ry) that stewards the development, ecosystem, governance and promotion of Robot Framework and its community." + }, + { + "term": "Robot Framework® Certified Professional", + "aliasses": ["RFCP"], + "abbreviation": "RFCP", + "definition": "The foundational certification level for Robot Framework that validates understanding of core concepts, syntax and basic control structures." + }, + { + "term": "Root Suite", + "aliasses": [], + "abbreviation": "", + "definition": "The top-level suite in a Robot Framework execution, determined by the initial directory or file path passed to the robot command." + }, + { + "term": "Scalar Access Syntax (${})", + "aliasses": [], + "abbreviation": "", + "definition": "The standard variable access form in Robot Framework used to read values regardless of whether the underlying variable was defined as scalar, list-like or dictionary-like." + }, + { + "term": "Scalar Variable", + "aliasses": [], + "abbreviation": "", + "definition": "A Robot Framework variable accessed with the ${} syntax that holds a single value of any supported data type." + }, + { + "term": "Skip Status", + "aliasses": [], + "abbreviation": "", + "definition": "An execution status indicating that an element (such as a test or task) was intentionally not executed, for example due to selection options or an explicit skip." + }, + { + "term": "Standard Library (Robot Framework)", + "aliasses": [], + "abbreviation": "", + "definition": "A library that is shipped with Robot Framework itself, providing generic functionality such as operating system interaction, string manipulation, or process handling." + }, + { + "term": "Suite (Test Suite / Task Suite)", + "aliasses": [], + "abbreviation": "", + "definition": "A collection of tests or tasks (and optionally local keywords and variables) defined in a .robot file or directory that is executed as a unit by Robot Framework." + }, + { + "term": "Suite File", + "aliasses": [], + "abbreviation": "", + "definition": "A .robot file that contains at least one test case or task and is therefore treated by Robot Framework as an executable suite." + }, + { + "term": "Suite Setup", + "aliasses": [], + "abbreviation": "", + "definition": "A keyword executed once before any tests|tasks in a suite are run, typically used to prepare common preconditions." + }, + { + "term": "Suite Teardown", + "aliasses": [], + "abbreviation": "", + "definition": "A keyword executed once after all tests|tasks in a suite have run, typically used to clean up shared resources." + }, + { + "term": "Suite Variable", + "aliasses": [], + "abbreviation": "", + "definition": "A variable whose scope covers all tests|tasks and keywords within a specific suite but is not visible outside that suite." + }, + { + "term": "Synthetic Monitoring", + "aliasses": ["Active Monitoring"], + "abbreviation": "", + "definition": "A proactive monitoring technique that runs automated scripts (often using tools like Robot Framework) at regular intervals against live systems to detect issues before real users are affected." + }, + { + "term": "Task", + "aliasses": ["Test Case"], + "abbreviation": "", + "definition": "An executable entity in Robot Framework similar to a test case but conceptually used for non-testing automation such as RPA workflows; defined in a *** Tasks *** section." + }, + { + "term": "Test Setup", + "aliasses": ["Task Setup"], + "abbreviation": "", + "definition": "A keyword executed before an individual test or task starts, used to prepare preconditions specific to that test|task." + }, + { + "term": "Test Teardown", + "aliasses": ["Task Teardown"], + "abbreviation": "", + "definition": "A keyword executed after an individual test or task finishes, used to clean up resources specific to that test|task." + }, + { + "term": "Test Template", + "aliasses": ["Task Template"], + "abbreviation": "", + "definition": "A setting that defines a keyword used as a template for multiple tests|tasks, where each row of data calls the template keyword with different arguments." + }, + { + "term": "Test Case", + "aliasses": ["Task"], + "abbreviation": "Test", + "definition": "An executable specification in Robot Framework that verifies some aspect of a system’s behavior and is defined in a *** Test Cases *** section." + }, + { + "term": "Test Data", + "aliasses": [], + "abbreviation": "", + "definition": "The collection of suites, tests, tasks, resource files, keywords and variables that define what Robot Framework will execute." + }, + { + "term": "Test Level", + "aliasses": [], + "abbreviation": "", + "definition": "A classification of testing focus (such as unit, component, integration, system, system integration, acceptance or end-to-end) describing the scope and granularity of tests." + }, + { + "term": "Test Tag", + "aliasses": ["Task Tag"], + "abbreviation": "", + "definition": "A label assigned to tests or tasks (using the Tags setting) to categorize them and enable filtering, selection and reporting." + }, + { + "term": "Test Timeout", + "aliasses": ["Task Timeout"], + "abbreviation": "", + "definition": "A maximum allowed execution time for a keyword, test or task after which Robot Framework marks the element as failed due to timeout." + }, + { + "term": "User Keyword", + "aliasses": ["Composite Keyword"], + "abbreviation": "", + "definition": "A keyword defined in Robot Framework syntax (typically in suites or resource files) that is composed of calls to other keywords and statements, often used to describe higher-level or business-oriented actions." + }, + { + "term": "Variable", + "aliasses": [], + "abbreviation": "", + "definition": "A named reference to a value or collection of values in Robot Framework, used to store data and pass it between keywords, tests and tasks." + }, + { + "term": "Variable File", + "aliasses": [], + "abbreviation": "", + "definition": "A separate file (often a Python module or other supported format) that provides variables which can be imported into suites using the Variables setting." + }, + { + "term": "Variable Scope", + "aliasses": [], + "abbreviation": "", + "definition": "The visibility and lifetime of a variable (such as global, suite, test|task, or local) during a Robot Framework execution." + }, + { + "term": "WHILE Loop", + "aliasses": [], + "abbreviation": "", + "definition": "A control structure in Robot Framework that repeatedly executes a block of keywords as long as a given condition evaluates to true." + } +] From 92e50270ccb32c6beed552ba5eb89126485c53cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9?= <41592183+Snooz82@users.noreply.github.com> Date: Fri, 5 Dec 2025 22:10:33 +0100 Subject: [PATCH 03/12] Update website/static/glossary/glossary.json Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- website/static/glossary/glossary.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/static/glossary/glossary.json b/website/static/glossary/glossary.json index 6064494..0373d9b 100644 --- a/website/static/glossary/glossary.json +++ b/website/static/glossary/glossary.json @@ -93,7 +93,7 @@ "term": "End-to-End Test", "aliasses": [], "abbreviation": "", - "definition": "Tests that verifies complete workflows across all relevant components, subsystems and interfaces to ensure that real-world user flows behave as expected." + "definition": "Tests that verify complete workflows across all relevant components, subsystems and interfaces to ensure that real-world user flows behave as expected." }, { "term": "Execution Artifacts", From d6171b7e62f9806ef3ecf5fd4d811c86bc6a83a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rene=CC=81?= Date: Sat, 6 Dec 2025 00:22:31 +0100 Subject: [PATCH 04/12] implemented glossary tooltips MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: René --- LOs.csv | 2 +- README.md | 2 +- website/docs/chapter-01/04_styles.md | 2 +- .../docs/chapter-02/05_keyword_interface.md | 50 +++---- website/docs/chapter-02/06_writing_test.md | 6 +- website/docs/chapter-03/03_user_keyword.md | 6 +- website/docs/learning_objectives.md | 2 +- .../src/components/Glossary/GlossaryTable.tsx | 17 ++- website/src/components/Term.tsx | 141 ++++++++++++------ website/src/remark/remark-term-directive.js | 126 ++++++++++------ website/static/glossary/glossary.json | 50 +++++-- 11 files changed, 265 insertions(+), 139 deletions(-) diff --git a/LOs.csv b/LOs.csv index f072ba2..83be89a 100644 --- a/LOs.csv +++ b/LOs.csv @@ -50,7 +50,7 @@ LO-2.5.2.3,(K1),Recall the concept of keywords with embedded arguments used in B 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.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.,,, diff --git a/README.md b/README.md index 0c81f8c..0d77c7e 100644 --- a/README.md +++ b/README.md @@ -113,7 +113,7 @@ - [`2.5.2.6 Named-Only Arguments`](website/docs/chapter-02/05_keyword_interface.md#2526-named-only-arguments) - LO-2.5.2.6 (K1) Recall what properties "Named-Only Arguments" have and how they are documented. - [`2.5.2.7 Free Named Arguments`](website/docs/chapter-02/05_keyword_interface.md#2527-free-named-arguments) - - LO-2.5.2.7 (K1) Recall how free named arguments are marked in documentation. + - LO-2.5.2.7 (K1) Recall how "Free Named Arguments" are marked in documentation. - [`2.5.2.8 Argument Types`](website/docs/chapter-02/05_keyword_interface.md#2528-argument-types) - LO-2.5.2.8 (K2) Understand the concept of argument types and automatic type conversion. - [`2.5.2.9 Return Types`](website/docs/chapter-02/05_keyword_interface.md#2529-return-types) diff --git a/website/docs/chapter-01/04_styles.md b/website/docs/chapter-01/04_styles.md index 5da19d4..f8be697 100644 --- a/website/docs/chapter-01/04_styles.md +++ b/website/docs/chapter-01/04_styles.md @@ -16,7 +16,7 @@ While **Keyword-Driven Testing (KDT)** and **Behavior-Driven Development (BDD)** Both styles can be mixed, even within the same test or task, but it is strongly recommended to have separate styles for separate purposes and not mix them within the same body. One practical solution would be to define acceptance test cases that cover users' expectations in a declarative *Behavior-Driven Style*, while using keywords that are implemented in an imperative *Keyword-Driven style*. -Further system level test cases, that are not covering acceptance criteria could be written in a *Keyword-Driven style*. +Further system level :term[test cases](Test Case), that are not covering acceptance criteria could be written in a *Keyword-Driven style*. The approach of both styles is different in that way, that the *Behavior-Driven Style* is a **declarative** specification, diff --git a/website/docs/chapter-02/05_keyword_interface.md b/website/docs/chapter-02/05_keyword_interface.md index 0c7e930..4f9c4bd 100644 --- a/website/docs/chapter-02/05_keyword_interface.md +++ b/website/docs/chapter-02/05_keyword_interface.md @@ -70,14 +70,14 @@ 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 Mandatory Arguments `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. +The argument `arguments` is a :term[Variable Number of Positional Arguments] and can only be set by position. Therefore, if it shall be set, all preceding arguments must be set by position as well. See [2.5.2.5 Variable Number of Positional Arguments](chapter-02/05_keyword_interface.md#2525-variable-number-of-positional-arguments) for more information about this kind of argument. -The argument `configuration` is a "Free Named Argument" and can only be set by names. +The argument `configuration` is a :term[Free Named Argument] and can only be set by names. See [2.5.2.7 Free Named Arguments](chapter-02/05_keyword_interface.md#2527-free-named-arguments) for more information about this kind of argument. @@ -92,11 +92,11 @@ See [2.5.2.7 Free Named Arguments](chapter-02/05_keyword_interface.md#2527-free- This keyword has 2 "Mandatory Arguments" that can be called positionally or by name. The last two arguments are optional. -The argument `groups` is a "Variable Number of Positional Arguments" and can only be set by position. +The argument `groups` is a :term[Variable Number of Positional Arguments] and can only be set by position. Therefore, if it shall be set, all preceding arguments must be set by position as well. See [2.5.2.5 Variable Number of Positional Arguments](chapter-02/05_keyword_interface.md#2525-variable-number-of-positional-arguments) for more information about this kind of argument. -The argument `flags` is a "Named-Only Argument" and can only be set by name. +The argument `flags` is a :term[Named-Only Argument] and can only be set by name. See [2.5.2.6 Named-Only Arguments](chapter-02/05_keyword_interface.md#2526-named-only-arguments) for more information about this kind of argument. @@ -118,20 +118,20 @@ The more business oriented keywords are the less arguments they typically have. Keyword arguments can be grouped into different argument kinds. On the one hand you can group them by their definition attributes and on the other hand by their usage kind. -The relevant distinction of usage kinds is between using **Positional Arguments**, **Named Arguments**, or **Embedded Arguments**. +The relevant distinction of usage kinds is between using :term[Positional Arguments]{term="Positional Argument"}, :term[Named Arguments]{term="Named Argument"}, or :term[Embedded Arguments]{term="Embedded Argument"}. How to use them is described in [2.6 Writing Test|Task and Calling Keywords](chapter-02/06_writing_test.md). Another important information is if an argument is mandatory or optional. See the next two sections for more information about these two kinds of arguments. Most arguments can either be set by their position or by their name. -But there are some kinds of arguments that can only be set positionally, like **Variable Number of Positional Arguments**, or only be set named, like **Named-Only Arguments** or **Free Named Arguments**. +But there are some kinds of arguments that can only be set positionally, like :term[Variable Number of Positional Arguments], or only be set named, like :term[Named-Only Arguments]{term="Named-Only Argument"} or :term[Free Named Arguments]{term="Free Named Argument"}. The order is as follows: -1. **Positional or Named Arguments** (can be mandatory or optional) -2. **Variable Number of Positional Arguments** (optional) -3. **Named-Only Arguments** (can be mandatory or optional) -4. **Free Named Arguments** (optional) +1. :term[Positional or Named Arguments]{term="Positional or Named Argument"} (can be mandatory or optional) +2. :term[Variable Number of Positional Arguments] (optional) +3. :term[Named-Only Arguments]{term="Named-Only Argument"} (can be mandatory or optional) +4. :term[Free Named Arguments]{term="Free Named Argument"} (optional) ### 2.5.2.1 Mandatory Arguments @@ -189,7 +189,7 @@ Arguments that have a default value can be omitted when the keyword is called, c These arguments are listed after the mandatory arguments in the argument interface. Default values are defined and represented in the docs by the equal sign `=` after the argument name and a value after that. -Also "Variable Number of Positional Arguments", represented with a single star (`*`) prefix, and "Free Named Arguments", represented with a double star (`**`) prefix are optional arguments. +Also :term[Variable Number of Positional Arguments], represented with a single star (`*`) prefix, and :term[Free Named Arguments]{term="Free Named Argument"}, represented with a double star (`**`) prefix are optional arguments. E.g. the argument `msg` in the `Should Be Equal` keyword documentation has the default value `None` and `ignore_case` has the default value `False`. @@ -233,7 +233,7 @@ Foundation Page should be Accessible And the url should be https://robotframework.org/foundation ``` The optional prefixes `Given`, `When`, `Then`, `And` and `But` are basically ignored by Robot Framework if a keyword is found matching the rest of the name including the embedded arguments. -In the example test case some keywords are designed so that the arguments are surrounded by double quotes (`"`) for better visibility. +In the example :term[test case] some keywords are designed so that the arguments are surrounded by double quotes (`"`) for better visibility. A mix of embedded arguments and "normal" arguments is possible to fully support BDD. In the keyword documentation the embedded arguments are written in variable syntax with dollar-curly-braces (`${var_name}`) to indicate that they are not part of the keyword name but are arguments. @@ -253,7 +253,7 @@ Recall how "Positional or Named Arguments" are marked in the documentation and t :::: Except for "Positional-Only Arguments", which are not part of this syllabus, -all arguments that are positioned before "Variable Number of Positional Arguments", "Named-Only Arguments", or "Free Named Arguments" in the argument interface of a keyword are "Positional or Named Arguments". +all arguments that are positioned before :term[Variable Number of Positional Arguments], :term[Named-Only Arguments]{term="Named-Only Argument"}, or :term[Free Named Arguments]{term="Free Named Argument"} in the argument interface of a keyword are :term[Positional or Named Arguments]{term="Positional or Named Argument"}. As their name states, they can be set either by their position or by their name, but not by both at the same time for one argument. If an argument shall be set by its position, all preceding arguments must be set by their position as well. @@ -275,7 +275,7 @@ Recall how "Variable Number of Positional Arguments" are marked in the documenta :::: -A special case of optional arguments that can only be set by their position are "Variable Number of Positional Arguments". +A special case of optional arguments that can only be set by their position are :term[Variable Number of Positional Arguments]. These are also referred to as `*args` or `*varargs` in Python. Some keywords need to collect a variable amount of values into one argument, because it is not possible to define the amount of values in advance. @@ -286,8 +286,8 @@ Depending on the command to be executed different amount of arguments are needed This variable argument is marked with a single asterisk `*` before the argument name in the keyword documentation. When calling this keyword, the first positional argument is assigned to `command`, while all subsequent positional arguments are collected into `arguments`. -Because of this behavior, no additional positional arguments can be used after these "Variable Number of Positional Arguments". -As a result, any arguments following these "Variable Number of Positional Arguments" must be named arguments, +Because of this behavior, no additional positional arguments can be used after these :term[Variable Number of Positional Arguments]. +As a result, any arguments following these :term[Variable Number of Positional Arguments] must be named arguments, regardless of whether they are mandatory or optional arguments with a default value. Also see [2.5.1.3 Example Keyword `Get Regexp Matches`](chapter-02/05_keyword_interface.md#2513-example-keyword-get-regexp-matches). @@ -305,15 +305,15 @@ Recall what properties "Named-Only Arguments" have and how they are documented. :::: -All arguments that are defined after a "Variable Number of Positional Arguments" (`*varargs`) are "Named-Only Arguments". -However it is also possible to create "Named-Only Arguments without a preceding "Variable Number of Positional Arguments". +All arguments that are defined after a :term[Variable Number of Positional Arguments] (`*varargs`) are :term[Named-Only Arguments]{term="Named-Only Argument"}. +However it is also possible to create "Named-Only Arguments without a preceding :term[Variable Number of Positional Arguments]. -"Named-Only Arguments" are marked with a "LABEL" sign `🏷` before the argument name in the keyword documentation. +:term[Named-Only Arguments]{term="Named-Only Argument"} are marked with a "LABEL" sign `🏷` before the argument name in the keyword documentation. -Those arguments can not be set positionally. All positional values would be consumed by the "Variable Number of Positional Arguments". +Those arguments can not be set positionally. All positional values would be consumed by the :term[Variable Number of Positional Arguments]. So they must be called by their name followed by an equal sign `=` and the value of the argument. -"Named-Only Arguments" can be mandatory or optional with a default value. +:term[Named-Only Arguments]{term="Named-Only Argument"} can be mandatory or optional with a default value. ### 2.5.2.7 Free Named Arguments @@ -321,14 +321,14 @@ So they must be called by their name followed by an equal sign `=` and the value :::K1[LO-2.5.2.7] -Recall how free named arguments are marked in documentation. +Recall how "Free Named Arguments" are marked in documentation. ::: :::: -Another special case of "Named-Only Arguments" are "Free Named Arguments." -These arguments are similar to the "Variable Number of Positional Arguments" in that they can collect multiple values. +Another special case of :term[Named-Only Arguments]{term="Named-Only Argument"} are :term[Free Named Arguments]{term="Free Named Argument"}. +These arguments are similar to the :term[Variable Number of Positional Arguments] in that they can collect multiple values. However, instead of collecting positional values, they gather all named values that are not explicitly defined as argument names. In this case all values given to the keyword as arguments, that do contain an unescaped equal sign (`=`) are considered as named arguments. diff --git a/website/docs/chapter-02/06_writing_test.md b/website/docs/chapter-02/06_writing_test.md index 7ebb4a9..1180f2c 100644 --- a/website/docs/chapter-02/06_writing_test.md +++ b/website/docs/chapter-02/06_writing_test.md @@ -76,7 +76,7 @@ Understand the concept of how to set argument values positionally. :::: When calling keywords, arguments can often be set positionally in the order they are defined in the keyword documentation. -An exception to this are "Named-Only Arguments" and "Free Named Arguments" that can only be set by their name. +An exception to this are :term[Named-Only Arguments]{term="Named-Only Argument"} and :term[Free Named Arguments]{term="Free Named Argument"} that can only be set by their name. However, only using positional values can lead to poor readability as you can see in the previous example: `Mixed Positional Arguments` Some keywords do not have an obvious order of arguments. @@ -100,7 +100,7 @@ Click on x and y Click On Coordinates x=82 y=70 ``` -Calling keywords that have a "Variable Number of Positional Arguments" does require to set all preceding arguments by their position if the "Variable Number of Positional Arguments" shall be set. +Calling keywords that have a :term[Variable Number of Positional Arguments] does require to set all preceding arguments by their position if the :term[Variable Number of Positional Arguments] shall be set. Example: ```robotframework @@ -134,7 +134,7 @@ Also setting one optional argument but leaving the others at their default value Named arguments are set by their name followed by an equal sign `=` and the value of the argument. All named arguments must be set after the positional arguments are set but can be set in any order. -Equal signs are valid argument values and could therefore be misinterpreted as named arguments, if the text before the equal sign is an existing argument name or if "Free Named Arguments" are available at the called keyword. +Equal signs are valid argument values and could therefore be misinterpreted as named arguments, if the text before the equal sign is an existing argument name or if :term[Free Named Arguments]{term="Free Named Argument"} are available at the called keyword. To prevent that, an equal sign in argument values can be escaped by a backslash `\`. Example of escaping conflicting equal signs: diff --git a/website/docs/chapter-03/03_user_keyword.md b/website/docs/chapter-03/03_user_keyword.md index 2e5e5d8..7a5f757 100644 --- a/website/docs/chapter-03/03_user_keyword.md +++ b/website/docs/chapter-03/03_user_keyword.md @@ -157,7 +157,7 @@ Understand the purpose and syntax of the [Arguments] setting in User Keywords. User Keywords can accept arguments, which make them more dynamic and reusable in various contexts. The `[Arguments]` setting is used to define the arguments a user keyword expects. -See also Chapter 2 [2.5.2 Keyword Arguments](chapter-02/05_keyword_interface.md#252-keyword-arguments) for an introduction to argument kinds. +See also [2.5.2 Keyword Arguments](chapter-02/05_keyword_interface.md#252-keyword-arguments) for an introduction to argument kinds. Arguments are defined by `[Arguments]` followed by the argument names separated by multiple spaces in the syntax of scalar variables. @@ -350,8 +350,8 @@ the user ${action} ### 3.3.5.4 Other Argument Kinds -Other argument kinds like **Named-Only Arguments**, **Free Named Arguments**, or -**Variable Number of Positional Arguments** should be known, +Other argument kinds like :term[Named-Only Arguments]{term="Named-Only Argument"}, :term[Free Named Arguments]{term="Free Named Argument"}, or +:term[Variable Number of Positional Arguments] should be known, but their definition and usage are not part of this syllabus. diff --git a/website/docs/learning_objectives.md b/website/docs/learning_objectives.md index b5d6012..e0832b2 100644 --- a/website/docs/learning_objectives.md +++ b/website/docs/learning_objectives.md @@ -52,7 +52,7 @@ | [`LO-2.5.2.4`](chapter-02/05_keyword_interface.md#2524-positional-or-named-arguments) | K1 | Recall how "Positional or Named Arguments" are marked in the documentation and their use case. | | [`LO-2.5.2.5`](chapter-02/05_keyword_interface.md#2525-variable-number-of-positional-arguments) | K1 | Recall how "Variable Number of Positional Arguments" are marked in the documentation and their use case. | | [`LO-2.5.2.6`](chapter-02/05_keyword_interface.md#2526-named-only-arguments) | K1 | Recall what properties "Named-Only Arguments" have and how they are documented. | -| [`LO-2.5.2.7`](chapter-02/05_keyword_interface.md#2527-free-named-arguments) | K1 | Recall how free named arguments are marked in documentation. | +| [`LO-2.5.2.7`](chapter-02/05_keyword_interface.md#2527-free-named-arguments) | K1 | Recall how "Free Named Arguments" are marked in documentation. | | [`LO-2.5.2.8`](chapter-02/05_keyword_interface.md#2528-argument-types) | K2 | Understand the concept of argument types and automatic type conversion. | | [`LO-2.5.2.9`](chapter-02/05_keyword_interface.md#2529-return-types) | K2 | Understand the concept of return type hints. | | [`LO-2.5.3`](chapter-02/05_keyword_interface.md#253-keyword-documentation--examples) | K2 | Understand how to read keyword documentation and how to interpret the examples. | diff --git a/website/src/components/Glossary/GlossaryTable.tsx b/website/src/components/Glossary/GlossaryTable.tsx index 4b671e6..498400c 100644 --- a/website/src/components/Glossary/GlossaryTable.tsx +++ b/website/src/components/Glossary/GlossaryTable.tsx @@ -123,7 +123,7 @@ const GlossaryTable: React.FC = () => { window.scrollTo({ top, behavior: 'smooth' }); } }, - [aliasToCanonicalSlug] + [] ); useEffect(() => { @@ -211,13 +211,24 @@ const GlossaryTable: React.FC = () => { id={entry.slug} className={clsx({ [styles.activeRow]: activeSlug === entry.slug })} onClick={handleClick} + tabIndex={0} + role="button" + onKeyDown={(event) => { + if ( + (event.key === 'Enter' || event.key === ' ') && + event.target === event.currentTarget + ) { + event.preventDefault(); + handleClick(); + } + }} >
{entry.term}
{entry.isAlias ? ( - // Hyperlink to term in alias definition cell + // Hyperlink to term in alias definition cell { const aliasSlug = slugify(alias); const target = aliasToCanonicalSlug.get(aliasSlug) || aliasSlug; return ( - // Link to alias term + // Link to alias term (null); + const [coords, setCoords] = React.useState<{top: number; left: number; width: number}>({ + top: 0, + left: 0, + width: 0, + }); + const [portalReady, setPortalReady] = React.useState(false); React.useEffect(() => { const onDocClick = (e: MouseEvent) => { @@ -37,6 +48,35 @@ export default function Term({ return () => document.removeEventListener("click", onDocClick); }, []); + React.useEffect(() => { + if (typeof window === "undefined") return; + setPortalReady(true); + }, []); + + const updatePosition = React.useCallback(() => { + if (!ref.current || typeof window === "undefined") return; + const rect = ref.current.getBoundingClientRect(); + const scrollY = window.scrollY || window.pageYOffset; + const scrollX = window.scrollX || window.pageXOffset; + setCoords({ + top: rect.top + scrollY + rect.height + 4, + left: rect.left + scrollX, + width: rect.width, + }); + }, []); + + React.useEffect(() => { + if (!open) return; + updatePosition(); + const handler = () => updatePosition(); + window.addEventListener("scroll", handler, true); + window.addEventListener("resize", handler); + return () => { + window.removeEventListener("scroll", handler, true); + window.removeEventListener("resize", handler); + }; + }, [open, updatePosition]); + const hasTooltip = Boolean(tooltipMd || tooltip || tooltipHtml || children); // If you expect authors to use "\n" in attribute strings, you can normalize them: @@ -57,9 +97,11 @@ export default function Term({ } style={{ position: "relative", + display: "inline-block", cursor: hasTooltip ? "help" : "default", - borderBottom: "1px solid currentcolor", + // borderBottom: "1px solid currentcolor", fontWeight: 600, + fontStyle: "italic", color: "var(--ifm-navbar-link-active-color)", }} aria-haspopup="dialog" @@ -68,54 +110,65 @@ export default function Term({ {/* Trigger text; for inline directives, this is the directive label */} {trigger ?? children} - {open && hasTooltip && ( - - {/* Priority: Markdown > plain text > HTML > children */} - {tooltipMdNormalized && ( -

, // example: map elements if you like + {open && hasTooltip && portalReady + ? createPortal( +

- {tooltipMdNormalized} - - )} + {tooltipMdNormalized && ( + , + document.body + ) + : null} ); } diff --git a/website/src/remark/remark-term-directive.js b/website/src/remark/remark-term-directive.js index 74539ae..ee94a67 100644 --- a/website/src/remark/remark-term-directive.js +++ b/website/src/remark/remark-term-directive.js @@ -1,13 +1,46 @@ // plugins/remark-term-directive.js import {visit} from "unist-util-visit"; +import glossary from "../../static/glossary/glossary.json"; /** - * Converts :term[Text]{prop="value"} into: - * Text + * Usage examples (inline): + * :term[visual text]{term="Glossary Term"} + * :term[Glossary Term] // falls back to the label if {term} is missing * - * Works for inline (:term[...]) and (optionally) block/containers (:::) if you want them. + * The label between [] becomes the visible text. The target term is resolved in + * this order: {term=...} attribute (preferred), then {target} or {ref}, then the + * label as a last resort. The legacy title ( ... ) syntax is deprecated. + * The tooltip is built from the glossary entry (definition) and includes a link + * to the glossary page. */ export default function remarkTermDirective() { + const normalizeKey = (value = "") => value.trim().toLowerCase(); + + const slugify = (text = "") => + text + .toLowerCase() + .replace(/[^a-z0-9]+/g, "-") + .replace(/(^-+|-+$)/g, ""); + + const glossaryByKey = new Map(); + (glossary || []).forEach((entry) => { + const key = normalizeKey(entry.term); + glossaryByKey.set(key, entry); + (entry.aliasses || []).forEach((alias) => { + glossaryByKey.set(normalizeKey(alias), entry); + }); + }); + + const baseUrl = (process.env.BASE_URL || "/").replace(/\/$/, ""); + + const toTooltipMd = (entry, fallbackTarget) => { + const termName = entry?.term || fallbackTarget; + const link = termName ? `${baseUrl}/docs/glossary?term=${encodeURIComponent(termName)}` : undefined; + if (!termName) return undefined; + if (!entry) return `[Open glossary entry](${link})`; + return `**${entry.term}**\n\n${entry.definition}\n\n[Open glossary entry](${link})`; + }; + const toAttrs = (attrs = {}) => Object.entries(attrs).map(([name, value]) => ({ type: "mdxJsxAttribute", @@ -20,50 +53,55 @@ export default function remarkTermDirective() { visit(tree, (node, index, parent) => { if (!parent) return; - // Inline form: :term[...] - if (node.type === "textDirective" && node.name === "term") { - const label = - node.label ?? - (node.children && node.children[0] && node.children[0].value) ?? - ""; - const mdxNode = { - type: "mdxJsxTextElement", - name: "Term", - attributes: toAttrs(node.attributes), - children: [{type: "text", value: label}], - }; - parent.children.splice(index, 1, mdxNode); - return index + 1; - } + const isTermDirective = + (node.type === "textDirective" || node.type === "leafDirective" || node.type === "containerDirective") && + node.name === "term"; - // Optional block forms if you ever want them: - // Leaf directive (single block line): :term[Heading]{...} - if (node.type === "leafDirective" && node.name === "term") { - const label = - node.label ?? - (node.children && node.children[0] && node.children[0].value) ?? - ""; - const mdxNode = { - type: "mdxJsxFlowElement", - name: "Term", - attributes: toAttrs(node.attributes), - children: [{type: "text", value: label}], - }; - parent.children.splice(index, 1, mdxNode); - return index + 1; - } + if (!isTermDirective) return; + + const label = + node.label ?? + (node.children && node.children[0] && node.children[0].value) ?? + ""; + + const attrTerm = node.attributes?.term || node.attributes?.target || node.attributes?.ref; + const legacyTitle = node.title; // from ( ... ) syntax + const fallbackLabel = label; + + const targetTerm = + (typeof attrTerm === "string" && attrTerm.trim()) || + (typeof legacyTitle === "string" && legacyTitle.trim()) || + (typeof fallbackLabel === "string" && fallbackLabel.trim()) || + ""; - // Container directive with :::term ... ::: - if (node.type === "containerDirective" && node.name === "term") { - const mdxNode = { - type: "mdxJsxFlowElement", - name: "Term", - attributes: toAttrs(node.attributes), - children: node.children || [], - }; - parent.children.splice(index, 1, mdxNode); - return index + 1; + const glossaryEntry = glossaryByKey.get(normalizeKey(targetTerm)); + if (process.env.NODE_ENV !== "production") { + if (!attrTerm && legacyTitle) { + console.warn("[remark-term-directive] title ( ... ) syntax is deprecated; use {term=...} instead"); + } + if (!glossaryEntry) { + // Dev-only hint when a directive target does not resolve to a glossary entry + console.warn(`[remark-term-directive] missing glossary entry for "${targetTerm}"`); + } } + const tooltipMd = toTooltipMd(glossaryEntry, targetTerm); + const id = slugify(glossaryEntry?.term || targetTerm); + + const baseAttributes = { + trigger: label, + id, + tooltipMd, + }; + + const mdxNode = { + type: node.type === "textDirective" ? "mdxJsxTextElement" : "mdxJsxFlowElement", + name: "Term", + attributes: toAttrs({...node.attributes, ...baseAttributes}), + children: [{type: "text", value: label}], + }; + + parent.children.splice(index, 1, mdxNode); + return index + 1; }); }; } diff --git a/website/static/glossary/glossary.json b/website/static/glossary/glossary.json index 0373d9b..3ea8825 100644 --- a/website/static/glossary/glossary.json +++ b/website/static/glossary/glossary.json @@ -69,7 +69,7 @@ "term": "Control Structure", "aliasses": [], "abbreviation": "", - "definition": "Statements like IF, FOR, WHILE, BREAK and CONTINUE used in Robot Framework to control the execution flow inside a test, task or keyword." + "definition": "Statements like `IF`, `FOR`, `WHILE`, `BREAK` and `CONTINUE` used in Robot Framework to control the execution flow inside a test, task or keyword." }, { "term": "Data-Driven Specification", @@ -87,7 +87,7 @@ "term": "Embedded Argument", "aliasses": [], "abbreviation": "", - "definition": "An argument whose value is part of the keyword name text itself, typically used in behavior-driven style steps like `Given \"robotframework.org\" is open`." + "definition": "An argument written directly into a keyword name using the `${}` variable syntax; its value is mandatory and must appear in that position when the keyword is called, often used in behavior-driven style steps." }, { "term": "End-to-End Test", @@ -125,6 +125,12 @@ "abbreviation": "", "definition": "A control structure in Robot Framework used to iterate over items in a list or other iterable and execute a body of keywords for each item." }, + { + "term": "Free Named Argument", + "aliasses": ["**kwargs"], + "abbreviation": "kwargs", + "definition": "A catch-all named argument kind marked with ** that gathers all named values not explicitly defined elsewhere into a dictionary; optional and supplied using name=value pairs." + }, { "term": "Generic Test Automation Architecture", "aliasses": ["gTAA"], @@ -165,13 +171,13 @@ "term": "Inline IF", "aliasses": [], "abbreviation": "", - "definition": "A compact IF statement form on a single line (IF [args]) used to execute one keyword conditionally without an END." + "definition": "A compact IF statement form on a single line (`IF [args]`) used to execute one keyword conditionally without an END." }, { "term": "K-Level (Knowledge Level)", "aliasses": [], "abbreviation": "", - "definition": "A categorization of learning objectives based on Bloom’s Taxonomy: K1 (Remember), K2 (Understand), and K3 (Apply), indicating the expected depth of knowledge." + "definition": "A categorization of learning objectives based on Bloom’s Taxonomy: **K1** (Remember), **K2** (Understand), and **K3** (Apply), indicating the expected depth of knowledge." }, { "term": "Keyword", @@ -201,7 +207,7 @@ "term": "List Variable", "aliasses": [], "abbreviation": "", - "definition": "A Robot Framework variable of list type, accessed with the @{} syntax, that can hold an ordered collection of values and can be unpacked when passed to keywords." + "definition": "A Robot Framework variable of list type, accessed with the `@{}` syntax, that can hold an ordered collection of values and can be unpacked when passed to keywords." }, { "term": "Local Variable", @@ -216,22 +222,22 @@ "definition": "A detailed HTML execution log generated by Robot Framework that shows keyword-level execution steps, arguments, messages and statuses." }, { - "term": "Metadata (Suite Metadata)", + "term": "Mandatory Argument", "aliasses": [], "abbreviation": "", - "definition": "Key–value information defined with the Metadata setting in a suite, used to document additional attributes such as author, version, or related requirements." + "definition": "Arguments without a default value that must be provided when calling a keyword; they appear before optional arguments and a call fails if they are missing." }, { - "term": "Named Argument", + "term": "Metadata (Suite Metadata)", "aliasses": [], "abbreviation": "", - "definition": "A keyword argument specified using its name followed by = and a value (for example timeout=10 seconds), allowing arguments to be provided in any order." + "definition": "Key–value information defined with the Metadata setting in a suite, used to document additional attributes such as author, version, or related requirements." }, { "term": "Named-Only Argument", - "aliasses": [], + "aliasses": ["Named Argument"], "abbreviation": "", - "definition": "A keyword argument that must be provided by name and cannot be given positionally." + "definition": "An argument that must be provided by name (never positionally); typically defined after a \"Variable Number of Positional Arguments\" or explicitly marked with a label icon in docs, and can be mandatory or optional." }, { "term": "Output File (output.xml)", @@ -239,6 +245,12 @@ "abbreviation": "", "definition": "The main machine-readable execution result file produced by Robot Framework, containing the full execution tree, messages, and statistics in XML format." }, + { + "term": "Optional Argument", + "aliasses": [], + "abbreviation": "", + "definition": "Arguments that have a default value or are optional catch-alls (such as a \"Variable Number of Positional Arguments\" marked with * or \"Free Named Arguments\" marked with **); they can be omitted, follow mandatory arguments in the interface, and default to predefined values when not provided." + }, { "term": "Pass Status", "aliasses": [], @@ -251,6 +263,12 @@ "abbreviation": "", "definition": "A keyword argument provided solely by its position in the argument list without naming it explicitly." }, + { + "term": "Positional or Named Argument", + "aliasses": [], + "abbreviation": "", + "definition": "Arguments that appear before a Variable Number of Positional Arguments or Named-Only Arguments and can be set either by position or by name (but not both for the same value); they may be mandatory or optional." + }, { "term": "Report File (report.html)", "aliasses": [], @@ -309,7 +327,7 @@ "term": "Scalar Variable", "aliasses": [], "abbreviation": "", - "definition": "A Robot Framework variable accessed with the ${} syntax that holds a single value of any supported data type." + "definition": "A Robot Framework variable accessed with the `${}` syntax that holds a single value of any supported data type." }, { "term": "Skip Status", @@ -387,7 +405,7 @@ "term": "Test Case", "aliasses": ["Task"], "abbreviation": "Test", - "definition": "An executable specification in Robot Framework that verifies some aspect of a system’s behavior and is defined in a *** Test Cases *** section." + "definition": "An executable specification in Robot Framework that verifies some aspect of a system’s behavior and is defined in a `*** Test Cases ***` section." }, { "term": "Test Data", @@ -419,6 +437,12 @@ "abbreviation": "", "definition": "A keyword defined in Robot Framework syntax (typically in suites or resource files) that is composed of calls to other keywords and statements, often used to describe higher-level or business-oriented actions." }, + { + "term": "Variable Number of Positional Arguments", + "aliasses": ["*varargs", "*args"], + "abbreviation": "", + "definition": "An optional argument kind marked with a single * that collects all remaining positional values; once present, any subsequent parameters must be provided as named arguments." + }, { "term": "Variable", "aliasses": [], From 91c34822e116565dd37185e416327c146892a0d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rene=CC=81?= Date: Sat, 6 Dec 2025 00:30:21 +0100 Subject: [PATCH 05/12] implemented glossary tooltips MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: René --- website/docs/chapter-02/05_keyword_interface.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/docs/chapter-02/05_keyword_interface.md b/website/docs/chapter-02/05_keyword_interface.md index 4f9c4bd..562f767 100644 --- a/website/docs/chapter-02/05_keyword_interface.md +++ b/website/docs/chapter-02/05_keyword_interface.md @@ -306,7 +306,7 @@ Recall what properties "Named-Only Arguments" have and how they are documented. :::: All arguments that are defined after a :term[Variable Number of Positional Arguments] (`*varargs`) are :term[Named-Only Arguments]{term="Named-Only Argument"}. -However it is also possible to create "Named-Only Arguments without a preceding :term[Variable Number of Positional Arguments]. +However it is also possible to create :term[Named-Only Arguments]{term="Named-Only Argument"} without a preceding :term[Variable Number of Positional Arguments]. :term[Named-Only Arguments]{term="Named-Only Argument"} are marked with a "LABEL" sign `🏷` before the argument name in the keyword documentation. From 3349f890bcd35f61b62753f62a51da9b425538b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rene=CC=81?= Date: Sat, 6 Dec 2025 00:33:55 +0100 Subject: [PATCH 06/12] fixed typos MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: René --- .../docs/chapter-02/05_keyword_interface.md | 2 +- .../src/components/Glossary/GlossaryTable.tsx | 6 +- website/src/remark/remark-term-directive.js | 2 +- website/static/glossary/glossary.json | 156 +++++++++--------- 4 files changed, 83 insertions(+), 83 deletions(-) diff --git a/website/docs/chapter-02/05_keyword_interface.md b/website/docs/chapter-02/05_keyword_interface.md index 562f767..ac13d0a 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 Mandatory Arguments `command` which can be called positionally or by name. +This keyword has one Mandatory Argument `command` which can be called positionally or by name. The latter two arguments are optional. The argument `arguments` is a :term[Variable Number of Positional Arguments] and can only be set by position. diff --git a/website/src/components/Glossary/GlossaryTable.tsx b/website/src/components/Glossary/GlossaryTable.tsx index 498400c..ddd6931 100644 --- a/website/src/components/Glossary/GlossaryTable.tsx +++ b/website/src/components/Glossary/GlossaryTable.tsx @@ -8,7 +8,7 @@ import styles from './GlossaryTable.module.css'; export type GlossaryItem = { term: string; - aliasses: string[]; + aliases: string[]; abbreviation: string; definition: string; }; @@ -56,13 +56,13 @@ const GlossaryTable: React.FC = () => { isAlias: false, slug, targetSlug: slug, - aliases: item.aliasses || [], + aliases: item.aliases || [], }; }); const aliasEntries: DisplayEntry[] = glossaryItems.flatMap((item) => { const canonicalSlug = slugify(item.term); - return (item.aliasses || []) + return (item.aliases || []) .filter((alias) => !termSet.has(alias)) .map((alias) => ({ term: alias, diff --git a/website/src/remark/remark-term-directive.js b/website/src/remark/remark-term-directive.js index ee94a67..8acb957 100644 --- a/website/src/remark/remark-term-directive.js +++ b/website/src/remark/remark-term-directive.js @@ -26,7 +26,7 @@ export default function remarkTermDirective() { (glossary || []).forEach((entry) => { const key = normalizeKey(entry.term); glossaryByKey.set(key, entry); - (entry.aliasses || []).forEach((alias) => { + (entry.aliases || []).forEach((alias) => { glossaryByKey.set(normalizeKey(alias), entry); }); }); diff --git a/website/static/glossary/glossary.json b/website/static/glossary/glossary.json index 3ea8825..db778d6 100644 --- a/website/static/glossary/glossary.json +++ b/website/static/glossary/glossary.json @@ -1,469 +1,469 @@ [ { "term": "Acceptance Testing", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "Testing that validates whether a system meets business requirements and is ready for deployment or release, often defined or reviewed by business stakeholders." }, { "term": "Adaptation Layer", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "The layer in the Generic Test Automation Architecture (gTAA) that connects Robot Framework to the System Under Test or automated systems via keyword libraries." }, { "term": "Atomic Element", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "An execution element such as a library keyword or Robot Framework language statement that does not contain child steps; its status is determined only by its own execution result." }, { "term": "Automation Script", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A Robot Framework suite, test, task, or keyword collection that automates a defined workflow or behavior." }, { "term": "Argument", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A value passed to a keyword when it is called to customize its behavior. Arguments can have different kinds (for example positional, named, embedded) and may be mandatory or optional." }, { "term": "Argument Interface", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "The complete, ordered list of arguments that a keyword accepts, including their names, kinds, default values and optional type hints, as shown in keyword documentation." }, { "term": "Behavior-Driven Development", - "aliasses": [], + "aliases": [], "abbreviation": "BDD", "definition": "A development approach and collaboration practice that describes system behavior in business-readable language, often using Given/When/Then phrasing." }, { "term": "Behavior-Driven Specification", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A declarative specification style in Robot Framework where tests|tasks describe system behavior from the user’s perspective, typically using natural-language-like steps with embedded arguments and prefixes such as Given/When/Then/And/But." }, { "term": "Built-In Variables", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "Special variables provided by Robot Framework that expose execution-related information such as paths, timestamps, and status without needing explicit definition." }, { "term": "Command Line Interface", - "aliasses": ["Robot Framework CLI"], + "aliases": ["Robot Framework CLI"], "abbreviation": "CLI", "definition": "The interface used to run Robot Framework from the command line (e.g. with the `robot` command), configure execution options, and pass arguments or variables." }, { "term": "Composite Element", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "An execution element that is composed of other elements (for example a suite composed of tests|tasks, a test|task composed of keywords, or a user keyword composed of child keywords and statements) and whose status is derived from its children." }, { "term": "Control Structure", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "Statements like `IF`, `FOR`, `WHILE`, `BREAK` and `CONTINUE` used in Robot Framework to control the execution flow inside a test, task or keyword." }, { "term": "Data-Driven Specification", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A style where the same logic or test flow is executed multiple times with different input and/or expected output data, often implemented using test|task templates in Robot Framework." }, { "term": "Definition Layer", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "The layer in the Generic Test Automation Architecture (gTAA) containing the test data, such as suites, tests, tasks, resource files, keywords, and variables written in Robot Framework syntax." }, { "term": "Embedded Argument", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "An argument written directly into a keyword name using the `${}` variable syntax; its value is mandatory and must appear in that position when the keyword is called, often used in behavior-driven style steps." }, { "term": "End-to-End Test", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "Tests that verify complete workflows across all relevant components, subsystems and interfaces to ensure that real-world user flows behave as expected." }, { "term": "Execution Artifacts", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "Files and outputs generated by Robot Framework execution, such as `output.xml`, `log.html`, and `report.html`, which document what was executed and with which results." }, { "term": "Execution Layer", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "The layer in the Generic Test Automation Architecture (gTAA) that includes Robot Framework’s parser, execution engine, logging, and reporting components which interpret test data and run keywords." }, { "term": "Execution Model", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "The internal representation created by Robot Framework after parsing suites, tests, tasks, and keywords, which the execution engine uses to perform automation." }, { "term": "Fail Status", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "An execution status indicating that an element (such as a keyword, test, task or suite) did not meet its expected outcome or raised an error during execution." }, { "term": "FOR Loop", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A control structure in Robot Framework used to iterate over items in a list or other iterable and execute a body of keywords for each item." }, { "term": "Free Named Argument", - "aliasses": ["**kwargs"], + "aliases": ["**kwargs"], "abbreviation": "kwargs", "definition": "A catch-all named argument kind marked with ** that gathers all named values not explicitly defined elsewhere into a dictionary; optional and supplied using name=value pairs." }, { "term": "Generic Test Automation Architecture", - "aliasses": ["gTAA"], + "aliases": ["gTAA"], "abbreviation": "gTAA", "definition": "A layered reference architecture for test automation that defines separation into definition, execution, and adaptation layers; used to describe Robot Framework’s role in an automation solution." }, { "term": "Given / When / Then / And / But", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "Conventional prefixes used in behavior-driven specification style. Robot Framework can ignore these prefixes when matching keywords if the remaining part of the name matches a keyword." }, { "term": "Global Variable", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A variable with global scope that can be accessed from all suites and keywords in a Robot Framework execution." }, { "term": "Higher-Level Suite (Suite Directory)", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A directory that is treated as a suite because it (directly or indirectly) contains at least one suite file; it groups lower-level suites into a suite tree." }, { "term": "Initialization File (__init__.robot)", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A suite file located in a directory that configures that directory as a suite and can define suite-level settings, variables, setups and teardowns for all contained suites." }, { "term": "Inline Comment", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A comment written either at the very beginning, or at the end of a line in a Robot Framework file, separated by at least two spaces and starting with a # so that it is ignored by the interpreter." }, { "term": "Inline IF", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A compact IF statement form on a single line (`IF [args]`) used to execute one keyword conditionally without an END." }, { "term": "K-Level (Knowledge Level)", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A categorization of learning objectives based on Bloom’s Taxonomy: **K1** (Remember), **K2** (Understand), and **K3** (Apply), indicating the expected depth of knowledge." }, { "term": "Keyword", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A named, reusable action or sequence of actions in Robot Framework that can be called from tests, tasks or other keywords and may accept arguments and may return values." }, { "term": "Keyword Interface", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "The documented information of a keyword, including its name, arguments (with kinds and types), return values, documentation, and examples, as exposed for example by HTML documentation or IDEs." }, { "term": "Keyword-Driven Specification", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "An imperative specification style in Robot Framework where tests|tasks are written as sequences of keyword calls with arguments, focusing on what actions are executed and in which order." }, { "term": "Keyword Library", - "aliasses": ["Library"], + "aliases": ["Library"], "abbreviation": "", "definition": "A collection of library keywords implemented typically in Python (or other languages) that Robot Framework imports to interact with external systems, perform computations or provide utility functions." }, { "term": "List Variable", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A Robot Framework variable of list type, accessed with the `@{}` syntax, that can hold an ordered collection of values and can be unpacked when passed to keywords." }, { "term": "Local Variable", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A variable whose scope is limited to a single keyword, test or task execution and is not visible outside of that body." }, { "term": "Log File (log.html)", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A detailed HTML execution log generated by Robot Framework that shows keyword-level execution steps, arguments, messages and statuses." }, { "term": "Mandatory Argument", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "Arguments without a default value that must be provided when calling a keyword; they appear before optional arguments and a call fails if they are missing." }, { "term": "Metadata (Suite Metadata)", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "Key–value information defined with the Metadata setting in a suite, used to document additional attributes such as author, version, or related requirements." }, { "term": "Named-Only Argument", - "aliasses": ["Named Argument"], + "aliases": ["Named Argument"], "abbreviation": "", "definition": "An argument that must be provided by name (never positionally); typically defined after a \"Variable Number of Positional Arguments\" or explicitly marked with a label icon in docs, and can be mandatory or optional." }, { "term": "Output File (output.xml)", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "The main machine-readable execution result file produced by Robot Framework, containing the full execution tree, messages, and statistics in XML format." }, { "term": "Optional Argument", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "Arguments that have a default value or are optional catch-alls (such as a \"Variable Number of Positional Arguments\" marked with * or \"Free Named Arguments\" marked with **); they can be omitted, follow mandatory arguments in the interface, and default to predefined values when not provided." }, { "term": "Pass Status", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "An execution status indicating that an element (such as a keyword, test, task or suite) executed successfully and its expectations were met." }, { "term": "Positional Argument", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A keyword argument provided solely by its position in the argument list without naming it explicitly." }, { "term": "Positional or Named Argument", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "Arguments that appear before a Variable Number of Positional Arguments or Named-Only Arguments and can be set either by position or by name (but not both for the same value); they may be mandatory or optional." }, { "term": "Report File (report.html)", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A high-level HTML summary of a Robot Framework execution that focuses on statistics and overall pass/fail status of suites and tests|tasks." }, { "term": "Resource File", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A file (commonly with extension .resource or .robot) that contains user keywords and variables and is imported by suites to share and reuse these artifacts." }, { "term": "Return Statement (RETURN)", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A statement used in user keywords to return one or more values that can be assigned to variables in the calling context." }, { "term": "Return Type Hint", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A documented indication of the type of value a keyword returns, helping users understand how to use the returned data." }, { "term": "Robotic Process Automation", - "aliasses": ["RPA"], + "aliases": ["RPA"], "abbreviation": "RPA", "definition": "Automation of business processes or tasks normally performed by humans, often across multiple systems, without necessarily focusing on testing." }, { "term": "Robot Framework Foundation", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "The non-profit association (Robot Framework ry) that stewards the development, ecosystem, governance and promotion of Robot Framework and its community." }, { "term": "Robot Framework® Certified Professional", - "aliasses": ["RFCP"], + "aliases": ["RFCP"], "abbreviation": "RFCP", "definition": "The foundational certification level for Robot Framework that validates understanding of core concepts, syntax and basic control structures." }, { "term": "Root Suite", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "The top-level suite in a Robot Framework execution, determined by the initial directory or file path passed to the robot command." }, { "term": "Scalar Access Syntax (${})", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "The standard variable access form in Robot Framework used to read values regardless of whether the underlying variable was defined as scalar, list-like or dictionary-like." }, { "term": "Scalar Variable", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A Robot Framework variable accessed with the `${}` syntax that holds a single value of any supported data type." }, { "term": "Skip Status", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "An execution status indicating that an element (such as a test or task) was intentionally not executed, for example due to selection options or an explicit skip." }, { "term": "Standard Library (Robot Framework)", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A library that is shipped with Robot Framework itself, providing generic functionality such as operating system interaction, string manipulation, or process handling." }, { "term": "Suite (Test Suite / Task Suite)", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A collection of tests or tasks (and optionally local keywords and variables) defined in a .robot file or directory that is executed as a unit by Robot Framework." }, { "term": "Suite File", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A .robot file that contains at least one test case or task and is therefore treated by Robot Framework as an executable suite." }, { "term": "Suite Setup", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A keyword executed once before any tests|tasks in a suite are run, typically used to prepare common preconditions." }, { "term": "Suite Teardown", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A keyword executed once after all tests|tasks in a suite have run, typically used to clean up shared resources." }, { "term": "Suite Variable", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A variable whose scope covers all tests|tasks and keywords within a specific suite but is not visible outside that suite." }, { "term": "Synthetic Monitoring", - "aliasses": ["Active Monitoring"], + "aliases": ["Active Monitoring"], "abbreviation": "", "definition": "A proactive monitoring technique that runs automated scripts (often using tools like Robot Framework) at regular intervals against live systems to detect issues before real users are affected." }, { "term": "Task", - "aliasses": ["Test Case"], + "aliases": ["Test Case"], "abbreviation": "", "definition": "An executable entity in Robot Framework similar to a test case but conceptually used for non-testing automation such as RPA workflows; defined in a *** Tasks *** section." }, { "term": "Test Setup", - "aliasses": ["Task Setup"], + "aliases": ["Task Setup"], "abbreviation": "", "definition": "A keyword executed before an individual test or task starts, used to prepare preconditions specific to that test|task." }, { "term": "Test Teardown", - "aliasses": ["Task Teardown"], + "aliases": ["Task Teardown"], "abbreviation": "", "definition": "A keyword executed after an individual test or task finishes, used to clean up resources specific to that test|task." }, { "term": "Test Template", - "aliasses": ["Task Template"], + "aliases": ["Task Template"], "abbreviation": "", "definition": "A setting that defines a keyword used as a template for multiple tests|tasks, where each row of data calls the template keyword with different arguments." }, { "term": "Test Case", - "aliasses": ["Task"], + "aliases": ["Task"], "abbreviation": "Test", "definition": "An executable specification in Robot Framework that verifies some aspect of a system’s behavior and is defined in a `*** Test Cases ***` section." }, { "term": "Test Data", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "The collection of suites, tests, tasks, resource files, keywords and variables that define what Robot Framework will execute." }, { "term": "Test Level", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A classification of testing focus (such as unit, component, integration, system, system integration, acceptance or end-to-end) describing the scope and granularity of tests." }, { "term": "Test Tag", - "aliasses": ["Task Tag"], + "aliases": ["Task Tag"], "abbreviation": "", "definition": "A label assigned to tests or tasks (using the Tags setting) to categorize them and enable filtering, selection and reporting." }, { "term": "Test Timeout", - "aliasses": ["Task Timeout"], + "aliases": ["Task Timeout"], "abbreviation": "", "definition": "A maximum allowed execution time for a keyword, test or task after which Robot Framework marks the element as failed due to timeout." }, { "term": "User Keyword", - "aliasses": ["Composite Keyword"], + "aliases": ["Composite Keyword"], "abbreviation": "", "definition": "A keyword defined in Robot Framework syntax (typically in suites or resource files) that is composed of calls to other keywords and statements, often used to describe higher-level or business-oriented actions." }, { "term": "Variable Number of Positional Arguments", - "aliasses": ["*varargs", "*args"], + "aliases": ["*varargs", "*args"], "abbreviation": "", "definition": "An optional argument kind marked with a single * that collects all remaining positional values; once present, any subsequent parameters must be provided as named arguments." }, { "term": "Variable", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A named reference to a value or collection of values in Robot Framework, used to store data and pass it between keywords, tests and tasks." }, { "term": "Variable File", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A separate file (often a Python module or other supported format) that provides variables which can be imported into suites using the Variables setting." }, { "term": "Variable Scope", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "The visibility and lifetime of a variable (such as global, suite, test|task, or local) during a Robot Framework execution." }, { "term": "WHILE Loop", - "aliasses": [], + "aliases": [], "abbreviation": "", "definition": "A control structure in Robot Framework that repeatedly executes a block of keywords as long as a given condition evaluates to true." } From 9041b6766ee4ae388b322aba10f7b8d5f9ffdd69 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rene=CC=81?= Date: Sat, 6 Dec 2025 12:24:58 +0100 Subject: [PATCH 07/12] updated glossary terms around Arguments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: René --- website/static/glossary/glossary.json | 162 +++++++++++++------------- 1 file changed, 84 insertions(+), 78 deletions(-) diff --git a/website/static/glossary/glossary.json b/website/static/glossary/glossary.json index db778d6..a595c57 100644 --- a/website/static/glossary/glossary.json +++ b/website/static/glossary/glossary.json @@ -3,295 +3,301 @@ "term": "Acceptance Testing", "aliases": [], "abbreviation": "", - "definition": "Testing that validates whether a system meets business requirements and is ready for deployment or release, often defined or reviewed by business stakeholders." + "definition": "Validation that a system satisfies agreed business requirements and is ready for deployment or release." }, { "term": "Adaptation Layer", "aliases": [], "abbreviation": "", - "definition": "The layer in the Generic Test Automation Architecture (gTAA) that connects Robot Framework to the System Under Test or automated systems via keyword libraries." + "definition": "Layer in the Generic Test Automation Architecture (gTAA) that connects Robot Framework to the System Under Test or other automated systems via keyword libraries." }, { "term": "Atomic Element", "aliases": [], "abbreviation": "", - "definition": "An execution element such as a library keyword or Robot Framework language statement that does not contain child steps; its status is determined only by its own execution result." + "definition": "Execution element without child steps whose status depends solely on its own execution result." }, { "term": "Automation Script", "aliases": [], "abbreviation": "", - "definition": "A Robot Framework suite, test, task, or keyword collection that automates a defined workflow or behavior." + "definition": "Robot Framework suite, test, task, or keyword collection that automates a defined workflow or behavior." }, { "term": "Argument", "aliases": [], "abbreviation": "", - "definition": "A value passed to a keyword when it is called to customize its behavior. Arguments can have different kinds (for example positional, named, embedded) and may be mandatory or optional." + "definition": "Value supplied to a keyword call as positional, named, or embedded input to configure its behavior." }, { "term": "Argument Interface", "aliases": [], "abbreviation": "", - "definition": "The complete, ordered list of arguments that a keyword accepts, including their names, kinds, default values and optional type hints, as shown in keyword documentation." + "definition": "Ordered specification of a keyword’s arguments, including kinds (for example positional-or-named, named-only, variable positional, free named, embedded), names, default values, and optional type hints." }, { "term": "Behavior-Driven Development", "aliases": [], "abbreviation": "BDD", - "definition": "A development approach and collaboration practice that describes system behavior in business-readable language, often using Given/When/Then phrasing." + "definition": "Development approach that describes system behavior in business-readable language, often using Given/When/Then phrasing." }, { "term": "Behavior-Driven Specification", "aliases": [], "abbreviation": "", - "definition": "A declarative specification style in Robot Framework where tests|tasks describe system behavior from the user’s perspective, typically using natural-language-like steps with embedded arguments and prefixes such as Given/When/Then/And/But." + "definition": "Declarative Robot Framework style where tests|tasks describe system behavior from the user perspective using natural-language-like steps with embedded arguments and optional Given/When/Then/And/But prefixes." }, { "term": "Built-In Variables", "aliases": [], "abbreviation": "", - "definition": "Special variables provided by Robot Framework that expose execution-related information such as paths, timestamps, and status without needing explicit definition." + "definition": "Variables provided by Robot Framework that expose execution-related information such as paths, timestamps, and status without explicit definition." }, { "term": "Command Line Interface", "aliases": ["Robot Framework CLI"], "abbreviation": "CLI", - "definition": "The interface used to run Robot Framework from the command line (e.g. with the `robot` command), configure execution options, and pass arguments or variables." + "definition": "Interface used to run Robot Framework from the command line (for example with the `robot` command), configure execution options, and pass arguments or variables." }, { "term": "Composite Element", "aliases": [], "abbreviation": "", - "definition": "An execution element that is composed of other elements (for example a suite composed of tests|tasks, a test|task composed of keywords, or a user keyword composed of child keywords and statements) and whose status is derived from its children." + "definition": "Execution element composed of child elements (for example suites with tests|tasks, tests|tasks with keywords, or user keywords with child steps) whose status is derived from its children." }, { "term": "Control Structure", "aliases": [], "abbreviation": "", - "definition": "Statements like `IF`, `FOR`, `WHILE`, `BREAK` and `CONTINUE` used in Robot Framework to control the execution flow inside a test, task or keyword." + "definition": "Statement such as `IF`, `FOR`, `WHILE`, `BREAK`, or `CONTINUE` that controls execution flow inside a test, task, or keyword." }, { "term": "Data-Driven Specification", "aliases": [], "abbreviation": "", - "definition": "A style where the same logic or test flow is executed multiple times with different input and/or expected output data, often implemented using test|task templates in Robot Framework." + "definition": "Specification style where the same logic or test flow is executed multiple times with varying input or expected output data, often implemented with test|task templates." }, { "term": "Definition Layer", "aliases": [], "abbreviation": "", - "definition": "The layer in the Generic Test Automation Architecture (gTAA) containing the test data, such as suites, tests, tasks, resource files, keywords, and variables written in Robot Framework syntax." + "definition": "Layer in the Generic Test Automation Architecture (gTAA) containing test data such as suites, tests, tasks, resource files, keywords, and variables written in Robot Framework syntax." }, { "term": "Embedded Argument", "aliases": [], "abbreviation": "", - "definition": "An argument written directly into a keyword name using the `${}` variable syntax; its value is mandatory and must appear in that position when the keyword is called, often used in behavior-driven style steps." + "definition": "Argument kind defined directly in a keyword name using `${}` syntax whose value must appear in that position in calls, often used in behavior-driven steps." }, { "term": "End-to-End Test", "aliases": [], "abbreviation": "", - "definition": "Tests that verify complete workflows across all relevant components, subsystems and interfaces to ensure that real-world user flows behave as expected." + "definition": "Test that verifies a complete workflow across all relevant components, subsystems, and interfaces to ensure real-world user flows behave as expected." }, { "term": "Execution Artifacts", "aliases": [], "abbreviation": "", - "definition": "Files and outputs generated by Robot Framework execution, such as `output.xml`, `log.html`, and `report.html`, which document what was executed and with which results." + "definition": "Files produced by Robot Framework execution—such as `output.xml`, `log.html`, and `report.html`—that document what was executed and with which results." }, { "term": "Execution Layer", "aliases": [], "abbreviation": "", - "definition": "The layer in the Generic Test Automation Architecture (gTAA) that includes Robot Framework’s parser, execution engine, logging, and reporting components which interpret test data and run keywords." + "definition": "Layer in the Generic Test Automation Architecture (gTAA) comprising Robot Framework’s parser, execution engine, logging, and reporting components that interpret test data and run keywords." }, { "term": "Execution Model", "aliases": [], "abbreviation": "", - "definition": "The internal representation created by Robot Framework after parsing suites, tests, tasks, and keywords, which the execution engine uses to perform automation." + "definition": "Internal representation created after parsing suites, tests, tasks, and keywords that the execution engine uses to perform automation." }, { "term": "Fail Status", "aliases": [], "abbreviation": "", - "definition": "An execution status indicating that an element (such as a keyword, test, task or suite) did not meet its expected outcome or raised an error during execution." + "definition": "Execution status indicating that an element (such as a keyword, test, task, or suite) did not meet its expected outcome or raised an error during execution." }, { "term": "FOR Loop", "aliases": [], "abbreviation": "", - "definition": "A control structure in Robot Framework used to iterate over items in a list or other iterable and execute a body of keywords for each item." + "definition": "Control structure used to iterate over items in a list or other iterable and execute a body of keywords for each item." }, { "term": "Free Named Argument", "aliases": ["**kwargs"], "abbreviation": "kwargs", - "definition": "A catch-all named argument kind marked with ** that gathers all named values not explicitly defined elsewhere into a dictionary; optional and supplied using name=value pairs." + "definition": "Catch-all named argument kind in a keyword specification, marked with **, that gathers all named values not explicitly defined elsewhere into a dictionary." }, { "term": "Generic Test Automation Architecture", "aliases": ["gTAA"], "abbreviation": "gTAA", - "definition": "A layered reference architecture for test automation that defines separation into definition, execution, and adaptation layers; used to describe Robot Framework’s role in an automation solution." + "definition": "Layered reference architecture for test automation that separates definition, execution, and adaptation layers and describes Robot Framework’s role in an automation solution." }, { "term": "Given / When / Then / And / But", "aliases": [], "abbreviation": "", - "definition": "Conventional prefixes used in behavior-driven specification style. Robot Framework can ignore these prefixes when matching keywords if the remaining part of the name matches a keyword." + "definition": "Conventional prefixes in behavior-driven specification style that Robot Framework can ignore when matching keywords if the remaining part of the name matches a keyword." }, { "term": "Global Variable", "aliases": [], "abbreviation": "", - "definition": "A variable with global scope that can be accessed from all suites and keywords in a Robot Framework execution." + "definition": "Variable with global scope that can be accessed from all suites and keywords in a Robot Framework execution." }, { "term": "Higher-Level Suite (Suite Directory)", "aliases": [], "abbreviation": "", - "definition": "A directory that is treated as a suite because it (directly or indirectly) contains at least one suite file; it groups lower-level suites into a suite tree." + "definition": "Directory treated as a suite because it directly or indirectly contains at least one suite file, grouping lower-level suites into a suite tree." }, { "term": "Initialization File (__init__.robot)", "aliases": [], "abbreviation": "", - "definition": "A suite file located in a directory that configures that directory as a suite and can define suite-level settings, variables, setups and teardowns for all contained suites." + "definition": "Suite file located in a directory that configures that directory as a suite and defines suite-level settings, variables, setups, and teardowns for contained suites." }, { "term": "Inline Comment", "aliases": [], "abbreviation": "", - "definition": "A comment written either at the very beginning, or at the end of a line in a Robot Framework file, separated by at least two spaces and starting with a # so that it is ignored by the interpreter." + "definition": "Comment at the beginning or end of a line in a Robot Framework file, separated by at least two spaces and starting with # so that it is ignored by the interpreter." }, { "term": "Inline IF", "aliases": [], "abbreviation": "", - "definition": "A compact IF statement form on a single line (`IF [args]`) used to execute one keyword conditionally without an END." + "definition": "Compact single-line IF statement (`IF [args]`) used to execute one keyword conditionally without an END." }, { "term": "K-Level (Knowledge Level)", "aliases": [], "abbreviation": "", - "definition": "A categorization of learning objectives based on Bloom’s Taxonomy: **K1** (Remember), **K2** (Understand), and **K3** (Apply), indicating the expected depth of knowledge." + "definition": "Categorization of learning objectives based on Bloom’s Taxonomy: K1 (Remember), K2 (Understand), and K3 (Apply), indicating expected depth of knowledge." }, { "term": "Keyword", "aliases": [], "abbreviation": "", - "definition": "A named, reusable action or sequence of actions in Robot Framework that can be called from tests, tasks or other keywords and may accept arguments and may return values." + "definition": "Named reusable action or sequence of actions in Robot Framework callable from tests, tasks, or other keywords that may accept arguments and return values." }, { "term": "Keyword Interface", "aliases": [], "abbreviation": "", - "definition": "The documented information of a keyword, including its name, arguments (with kinds and types), return values, documentation, and examples, as exposed for example by HTML documentation or IDEs." + "definition": "Documented information of a keyword—including name, arguments with kinds and types, return values, documentation, and examples—as exposed by HTML documentation or IDEs." }, { "term": "Keyword-Driven Specification", "aliases": [], "abbreviation": "", - "definition": "An imperative specification style in Robot Framework where tests|tasks are written as sequences of keyword calls with arguments, focusing on what actions are executed and in which order." + "definition": "Imperative Robot Framework style where tests|tasks are written as sequences of keyword calls with arguments, focusing on executed actions and their order." }, { "term": "Keyword Library", "aliases": ["Library"], "abbreviation": "", - "definition": "A collection of library keywords implemented typically in Python (or other languages) that Robot Framework imports to interact with external systems, perform computations or provide utility functions." + "definition": "Collection of library keywords implemented typically in Python (or other languages) that Robot Framework imports to interact with external systems, perform computations, or provide utility functions." }, { "term": "List Variable", "aliases": [], "abbreviation": "", - "definition": "A Robot Framework variable of list type, accessed with the `@{}` syntax, that can hold an ordered collection of values and can be unpacked when passed to keywords." + "definition": "Robot Framework variable of list type accessed with the `@{}` syntax that holds an ordered collection of values and can be unpacked when passed to keywords." }, { "term": "Local Variable", "aliases": [], "abbreviation": "", - "definition": "A variable whose scope is limited to a single keyword, test or task execution and is not visible outside of that body." + "definition": "Variable whose scope is limited to a single keyword, test, or task execution and is not visible outside that body." }, { "term": "Log File (log.html)", "aliases": [], "abbreviation": "", - "definition": "A detailed HTML execution log generated by Robot Framework that shows keyword-level execution steps, arguments, messages and statuses." + "definition": "Detailed HTML execution log (log.html) generated by Robot Framework that shows keyword-level execution steps, arguments, messages, and statuses." }, { "term": "Mandatory Argument", "aliases": [], "abbreviation": "", - "definition": "Arguments without a default value that must be provided when calling a keyword; they appear before optional arguments and a call fails if they are missing." + "definition": "Argument kind in a keyword specification without a default value that must be provided in calls and that precedes optional arguments." }, { "term": "Metadata (Suite Metadata)", "aliases": [], "abbreviation": "", - "definition": "Key–value information defined with the Metadata setting in a suite, used to document additional attributes such as author, version, or related requirements." + "definition": "Key–value information defined with the Metadata setting in a suite to document attributes such as author, version, or related requirements." }, { "term": "Named-Only Argument", - "aliases": ["Named Argument"], + "aliases": [], + "abbreviation": "", + "definition": "Argument kind in a keyword specification that must be provided by name (never positionally), typically defined after a Variable Number of Positional Arguments or explicitly marked, and that can be mandatory or optional." + }, + { + "term": "Named Argument", + "aliases": [], "abbreviation": "", - "definition": "An argument that must be provided by name (never positionally); typically defined after a \"Variable Number of Positional Arguments\" or explicitly marked with a label icon in docs, and can be mandatory or optional." + "definition": "Argument value provided in a keyword call using an explicit name=value pair." }, { "term": "Output File (output.xml)", "aliases": [], "abbreviation": "", - "definition": "The main machine-readable execution result file produced by Robot Framework, containing the full execution tree, messages, and statistics in XML format." + "definition": "Machine-readable execution result file (output.xml) produced by Robot Framework that contains the full execution tree, messages, and statistics in XML format." }, { "term": "Optional Argument", "aliases": [], "abbreviation": "", - "definition": "Arguments that have a default value or are optional catch-alls (such as a \"Variable Number of Positional Arguments\" marked with * or \"Free Named Arguments\" marked with **); they can be omitted, follow mandatory arguments in the interface, and default to predefined values when not provided." + "definition": "Argument kind in a keyword specification that may be omitted because it has a default value or is a catch-all (such as Variable Number of Positional Arguments marked with * or Free Named Arguments marked with **)." }, { "term": "Pass Status", "aliases": [], "abbreviation": "", - "definition": "An execution status indicating that an element (such as a keyword, test, task or suite) executed successfully and its expectations were met." + "definition": "Execution status indicating that an element (such as a keyword, test, task, or suite) executed successfully and met its expectations." }, { "term": "Positional Argument", "aliases": [], "abbreviation": "", - "definition": "A keyword argument provided solely by its position in the argument list without naming it explicitly." + "definition": "Argument value provided in a keyword call solely by its position in the argument list without naming it explicitly." }, { "term": "Positional or Named Argument", "aliases": [], "abbreviation": "", - "definition": "Arguments that appear before a Variable Number of Positional Arguments or Named-Only Arguments and can be set either by position or by name (but not both for the same value); they may be mandatory or optional." + "definition": "Argument kind in a keyword specification that can be set either by position or by name (but not both for the same value) and that may be mandatory or optional." }, { "term": "Report File (report.html)", "aliases": [], "abbreviation": "", - "definition": "A high-level HTML summary of a Robot Framework execution that focuses on statistics and overall pass/fail status of suites and tests|tasks." + "definition": "High-level HTML summary (report.html) of a Robot Framework execution that focuses on statistics and overall pass/fail status of suites and tests|tasks." }, { "term": "Resource File", "aliases": [], "abbreviation": "", - "definition": "A file (commonly with extension .resource or .robot) that contains user keywords and variables and is imported by suites to share and reuse these artifacts." + "definition": "File (commonly with extension .resource or .robot) that contains user keywords and variables and is imported by suites to share and reuse these artifacts." }, { "term": "Return Statement (RETURN)", "aliases": [], "abbreviation": "", - "definition": "A statement used in user keywords to return one or more values that can be assigned to variables in the calling context." + "definition": "Statement used in user keywords to return one or more values that can be assigned to variables in the calling context." }, { "term": "Return Type Hint", "aliases": [], "abbreviation": "", - "definition": "A documented indication of the type of value a keyword returns, helping users understand how to use the returned data." + "definition": "Documented indication of the type of value a keyword returns, helping users understand how to use the returned data." }, { "term": "Robotic Process Automation", @@ -303,168 +309,168 @@ "term": "Robot Framework Foundation", "aliases": [], "abbreviation": "", - "definition": "The non-profit association (Robot Framework ry) that stewards the development, ecosystem, governance and promotion of Robot Framework and its community." + "definition": "Non-profit association (Robot Framework ry) that stewards the development, ecosystem, governance, and promotion of Robot Framework and its community." }, { "term": "Robot Framework® Certified Professional", "aliases": ["RFCP"], "abbreviation": "RFCP", - "definition": "The foundational certification level for Robot Framework that validates understanding of core concepts, syntax and basic control structures." + "definition": "Foundational certification level for Robot Framework that validates understanding of core concepts, syntax, and basic control structures." }, { "term": "Root Suite", "aliases": [], "abbreviation": "", - "definition": "The top-level suite in a Robot Framework execution, determined by the initial directory or file path passed to the robot command." + "definition": "Top-level suite in a Robot Framework execution determined by the initial directory or file path passed to the `robot` command." }, { "term": "Scalar Access Syntax (${})", "aliases": [], "abbreviation": "", - "definition": "The standard variable access form in Robot Framework used to read values regardless of whether the underlying variable was defined as scalar, list-like or dictionary-like." + "definition": "Standard variable access form in Robot Framework used to read values regardless of whether the underlying variable was defined as scalar, list-like, or dictionary-like." }, { "term": "Scalar Variable", "aliases": [], "abbreviation": "", - "definition": "A Robot Framework variable accessed with the `${}` syntax that holds a single value of any supported data type." + "definition": "Robot Framework variable accessed with the `${}` syntax that holds a single value of any supported data type." }, { "term": "Skip Status", "aliases": [], "abbreviation": "", - "definition": "An execution status indicating that an element (such as a test or task) was intentionally not executed, for example due to selection options or an explicit skip." + "definition": "Execution status indicating that an element (such as a test or task) was intentionally not executed, for example due to selection options or an explicit skip." }, { "term": "Standard Library (Robot Framework)", "aliases": [], "abbreviation": "", - "definition": "A library that is shipped with Robot Framework itself, providing generic functionality such as operating system interaction, string manipulation, or process handling." + "definition": "Library shipped with Robot Framework itself providing generic functionality such as operating system interaction, string manipulation, or process handling." }, { "term": "Suite (Test Suite / Task Suite)", "aliases": [], "abbreviation": "", - "definition": "A collection of tests or tasks (and optionally local keywords and variables) defined in a .robot file or directory that is executed as a unit by Robot Framework." + "definition": "Collection of tests or tasks (optionally with local keywords and variables) defined in a .robot file or directory that is executed as a unit by Robot Framework." }, { "term": "Suite File", "aliases": [], "abbreviation": "", - "definition": "A .robot file that contains at least one test case or task and is therefore treated by Robot Framework as an executable suite." + "definition": ".robot file that contains at least one test case or task and is therefore treated by Robot Framework as an executable suite." }, { "term": "Suite Setup", "aliases": [], "abbreviation": "", - "definition": "A keyword executed once before any tests|tasks in a suite are run, typically used to prepare common preconditions." + "definition": "Keyword executed once before any tests|tasks in a suite are run, typically used to prepare common preconditions." }, { "term": "Suite Teardown", "aliases": [], "abbreviation": "", - "definition": "A keyword executed once after all tests|tasks in a suite have run, typically used to clean up shared resources." + "definition": "Keyword executed once after all tests|tasks in a suite have run, typically used to clean up shared resources." }, { "term": "Suite Variable", "aliases": [], "abbreviation": "", - "definition": "A variable whose scope covers all tests|tasks and keywords within a specific suite but is not visible outside that suite." + "definition": "Variable whose scope covers all tests|tasks and keywords within a specific suite but is not visible outside that suite." }, { "term": "Synthetic Monitoring", "aliases": ["Active Monitoring"], "abbreviation": "", - "definition": "A proactive monitoring technique that runs automated scripts (often using tools like Robot Framework) at regular intervals against live systems to detect issues before real users are affected." + "definition": "Proactive monitoring that runs automated scripts (often using tools like Robot Framework) at regular intervals against live systems to detect issues before real users are affected." }, { "term": "Task", "aliases": ["Test Case"], "abbreviation": "", - "definition": "An executable entity in Robot Framework similar to a test case but conceptually used for non-testing automation such as RPA workflows; defined in a *** Tasks *** section." + "definition": "Executable entity in Robot Framework similar to a test case but used for non-testing automation such as RPA workflows, defined in a `*** Tasks ***` section." }, { "term": "Test Setup", "aliases": ["Task Setup"], "abbreviation": "", - "definition": "A keyword executed before an individual test or task starts, used to prepare preconditions specific to that test|task." + "definition": "Keyword executed before an individual test or task starts to prepare preconditions specific to that test|task." }, { "term": "Test Teardown", "aliases": ["Task Teardown"], "abbreviation": "", - "definition": "A keyword executed after an individual test or task finishes, used to clean up resources specific to that test|task." + "definition": "Keyword executed after an individual test or task finishes to clean up resources specific to that test|task." }, { "term": "Test Template", "aliases": ["Task Template"], "abbreviation": "", - "definition": "A setting that defines a keyword used as a template for multiple tests|tasks, where each row of data calls the template keyword with different arguments." + "definition": "Setting that defines a keyword used as a template for multiple tests|tasks, where each row of data calls the template keyword with different arguments." }, { "term": "Test Case", "aliases": ["Task"], "abbreviation": "Test", - "definition": "An executable specification in Robot Framework that verifies some aspect of a system’s behavior and is defined in a `*** Test Cases ***` section." + "definition": "Executable specification in Robot Framework that verifies some aspect of system behavior and is defined in a `*** Test Cases ***` section." }, { "term": "Test Data", "aliases": [], "abbreviation": "", - "definition": "The collection of suites, tests, tasks, resource files, keywords and variables that define what Robot Framework will execute." + "definition": "Collection of suites, tests, tasks, resource files, keywords, and variables that define what Robot Framework executes." }, { "term": "Test Level", "aliases": [], "abbreviation": "", - "definition": "A classification of testing focus (such as unit, component, integration, system, system integration, acceptance or end-to-end) describing the scope and granularity of tests." + "definition": "Classification of testing focus (such as unit, component, integration, system, system integration, acceptance, or end-to-end) describing scope and granularity of tests." }, { "term": "Test Tag", "aliases": ["Task Tag"], "abbreviation": "", - "definition": "A label assigned to tests or tasks (using the Tags setting) to categorize them and enable filtering, selection and reporting." + "definition": "Label assigned to tests or tasks via the Tags setting to categorize them and enable filtering, selection, and reporting." }, { "term": "Test Timeout", "aliases": ["Task Timeout"], "abbreviation": "", - "definition": "A maximum allowed execution time for a keyword, test or task after which Robot Framework marks the element as failed due to timeout." + "definition": "Maximum allowed execution time for a keyword, test, or task after which Robot Framework marks the element as failed due to timeout." }, { "term": "User Keyword", "aliases": ["Composite Keyword"], "abbreviation": "", - "definition": "A keyword defined in Robot Framework syntax (typically in suites or resource files) that is composed of calls to other keywords and statements, often used to describe higher-level or business-oriented actions." + "definition": "Keyword defined in Robot Framework syntax (typically in suites or resource files) composed of calls to other keywords and statements, often describing higher-level or business-oriented actions." }, { "term": "Variable Number of Positional Arguments", "aliases": ["*varargs", "*args"], "abbreviation": "", - "definition": "An optional argument kind marked with a single * that collects all remaining positional values; once present, any subsequent parameters must be provided as named arguments." + "definition": "Optional argument kind in a keyword specification, marked with a single *, that collects all remaining positional values; once present, any subsequent parameters must be provided as named arguments." }, { "term": "Variable", "aliases": [], "abbreviation": "", - "definition": "A named reference to a value or collection of values in Robot Framework, used to store data and pass it between keywords, tests and tasks." + "definition": "Named reference to a value or collection of values in Robot Framework used to store data and pass it between keywords, tests, and tasks." }, { "term": "Variable File", "aliases": [], "abbreviation": "", - "definition": "A separate file (often a Python module or other supported format) that provides variables which can be imported into suites using the Variables setting." + "definition": "File (often a Python module or other supported format) that provides variables which can be imported into suites using the Variables setting." }, { "term": "Variable Scope", "aliases": [], "abbreviation": "", - "definition": "The visibility and lifetime of a variable (such as global, suite, test|task, or local) during a Robot Framework execution." + "definition": "Visibility and lifetime of a variable (such as global, suite, test|task, or local) during a Robot Framework execution." }, { "term": "WHILE Loop", "aliases": [], "abbreviation": "", - "definition": "A control structure in Robot Framework that repeatedly executes a block of keywords as long as a given condition evaluates to true." + "definition": "Control structure in Robot Framework that repeatedly executes a block of keywords as long as a given condition evaluates to true." } ] From 8ebbf11a8b01b018dc21779da3e3671191e4d52f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9?= <41592183+Snooz82@users.noreply.github.com> Date: Sun, 7 Dec 2025 13:29:09 +0100 Subject: [PATCH 08/12] Apply suggestions from code review Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- website/docs/chapter-01/04_styles.md | 2 +- .../components/Glossary/GlossaryTable.module.css | 13 +------------ 2 files changed, 2 insertions(+), 13 deletions(-) diff --git a/website/docs/chapter-01/04_styles.md b/website/docs/chapter-01/04_styles.md index f8be697..3a7b2a8 100644 --- a/website/docs/chapter-01/04_styles.md +++ b/website/docs/chapter-01/04_styles.md @@ -16,7 +16,7 @@ While **Keyword-Driven Testing (KDT)** and **Behavior-Driven Development (BDD)** Both styles can be mixed, even within the same test or task, but it is strongly recommended to have separate styles for separate purposes and not mix them within the same body. One practical solution would be to define acceptance test cases that cover users' expectations in a declarative *Behavior-Driven Style*, while using keywords that are implemented in an imperative *Keyword-Driven style*. -Further system level :term[test cases](Test Case), that are not covering acceptance criteria could be written in a *Keyword-Driven style*. +Further system level :term[test cases]{term="Test Case"}, that are not covering acceptance criteria could be written in a *Keyword-Driven style*. The approach of both styles is different in that way, that the *Behavior-Driven Style* is a **declarative** specification, diff --git a/website/src/components/Glossary/GlossaryTable.module.css b/website/src/components/Glossary/GlossaryTable.module.css index 4016e6f..bd6ebc4 100644 --- a/website/src/components/Glossary/GlossaryTable.module.css +++ b/website/src/components/Glossary/GlossaryTable.module.css @@ -39,13 +39,6 @@ table-layout: fixed; } -.termCol { - width: 28%; -} - -.definitionCol { - width: 72%; -} th, td { @@ -91,11 +84,7 @@ tbody tr { width: 100%; } -.emptyState { - text-align: center; - padding: 1rem; - color: var(--ifm-color-emphasis-700); -} + .definitionText > :first-child { margin-top: 0; From 74638ac750f022e5c34f6f2612ed5332c797e19c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rene=CC=81?= Date: Sun, 7 Dec 2025 14:16:41 +0100 Subject: [PATCH 09/12] improved css of glossary terms MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: René --- .../src/components/Glossary/GlossaryTable.tsx | 1 + website/src/components/Term.module.css | 36 +++++++++++++++ website/src/components/Term.tsx | 45 ++++++------------- 3 files changed, 50 insertions(+), 32 deletions(-) create mode 100644 website/src/components/Term.module.css diff --git a/website/src/components/Glossary/GlossaryTable.tsx b/website/src/components/Glossary/GlossaryTable.tsx index ddd6931..2b1e63d 100644 --- a/website/src/components/Glossary/GlossaryTable.tsx +++ b/website/src/components/Glossary/GlossaryTable.tsx @@ -213,6 +213,7 @@ const GlossaryTable: React.FC = () => { onClick={handleClick} tabIndex={0} role="button" + aria-label={`View details for ${entry.term}`} onKeyDown={(event) => { if ( (event.key === 'Enter' || event.key === ' ') && diff --git a/website/src/components/Term.module.css b/website/src/components/Term.module.css new file mode 100644 index 0000000..34010b7 --- /dev/null +++ b/website/src/components/Term.module.css @@ -0,0 +1,36 @@ +.termTrigger { + position: relative; + cursor: help; + background: var(--ifm-background-surface-color); + border: 0.1rem solid var(--ifm-color-emphasis-300) !important; + border-radius: var(--ifm-code-border-radius) !important; + padding: 0 var(--ifm-code-padding-horizontal); + vertical-align: middle; +} + +.termTooltip { + position: absolute; + max-width: 420px; + font-weight: 400; + color: var(--ifm-font-color-base); + padding: 10px 12px; + border-radius: 8px; + background: var(--ifm-background-surface-color); + border: 1px solid var(--ifm-color-emphasis-300); + box-shadow: 0 8px 30px rgba(0, 0, 0, 0.15); + z-index: 1000; + white-space: normal; +} + +.termTooltipLink { + display: inline-flex; + align-items: center; + gap: 0.25rem; + padding: 0.15rem 0.6rem; + border-radius: 999px; + font-size: 0.8rem; + border: 1px solid var(--ifm-color-emphasis-300); + background: var(--ifm-color-emphasis-100); + color: var(--ifm-font-color-base); + text-decoration: none; +} diff --git a/website/src/components/Term.tsx b/website/src/components/Term.tsx index 3e152fd..6459378 100644 --- a/website/src/components/Term.tsx +++ b/website/src/components/Term.tsx @@ -7,6 +7,8 @@ import remarkGfm from "remark-gfm"; import rehypeRaw from "rehype-raw"; import DOMPurify from "dompurify"; +import styles from "./Term.module.css"; + type TermProps = { /** Text that appears inline in your document (the trigger/label) */ trigger?: string; // used by container form; fine to keep even if you only use inline @@ -95,15 +97,7 @@ export default function Term({ ? setOpen((v) => !v) : null } - style={{ - position: "relative", - display: "inline-block", - cursor: hasTooltip ? "help" : "default", - // borderBottom: "1px solid currentcolor", - fontWeight: 600, - fontStyle: "italic", - color: "var(--ifm-navbar-link-active-color)", - }} + className={styles.termTrigger} aria-haspopup="dialog" aria-expanded={open} > @@ -114,20 +108,10 @@ export default function Term({ ? createPortal(
@@ -139,18 +123,15 @@ export default function Term({ p: ({node: _node, ...props}) =>
, a: ({node: _node, href, ...props}) => { const resolvedHref = href && href.startsWith("/") ? `${baseUrl}${href}` : href; - return ; + return ( + + ); }, }} > From 8317d45afe4441cc1d02f43b30ff3508f8d70a7e Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Sun, 7 Dec 2025 14:18:37 +0100 Subject: [PATCH 10/12] Optimize GlossaryTable: pre-compute sanitized HTML (#73) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - [x] Revert to useMemo approach for entries and aliasToCanonicalSlug - [x] Remove unnecessary purifyRef and purifyReady state - [x] Simplify sanitization logic while maintaining security - [x] Ensure proper SSR handling - [x] Test and validate changes (TypeScript passes, dev server runs) - [x] Clean up build artifacts from repository - [x] Code review and security checks passed (CodeQL found no issues) --- 💬 We'd love your input! Share your thoughts on Copilot coding agent in our [2 minute survey](https://gh.io/copilot-coding-agent-survey). --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Snooz82 <41592183+Snooz82@users.noreply.github.com> Co-authored-by: René Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- website/.gitignore | 10 ++++++++++ website/src/components/Glossary/GlossaryTable.tsx | 12 ++++++------ website/src/components/Quiz/quizComponents.ts | 2 +- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/website/.gitignore b/website/.gitignore index b2d6de3..4244041 100644 --- a/website/.gitignore +++ b/website/.gitignore @@ -8,6 +8,16 @@ .docusaurus .cache-loader +# Build artifacts - TypeScript compiled JS files from TS sources +docusaurus.config.js +sidebars.js +/src/components/**/*.js +/src/pages/**/*.js +/src/theme/**/*.js +# Keep these JS files that are source files, not build artifacts: +!/src/components/Quiz/quizPrebuild.js +!/src/remark/*.js + # Misc .DS_Store .env.local diff --git a/website/src/components/Glossary/GlossaryTable.tsx b/website/src/components/Glossary/GlossaryTable.tsx index 2b1e63d..24a1d8c 100644 --- a/website/src/components/Glossary/GlossaryTable.tsx +++ b/website/src/components/Glossary/GlossaryTable.tsx @@ -17,6 +17,7 @@ export type DisplayEntry = { term: string; abbreviation: string; definition: string; + definitionHtml: string; canonicalTerm: string; isAlias: boolean; slug: string; @@ -30,9 +31,9 @@ const slugify = (text: string): string => .replace(/[^a-z0-9]+/g, '-') .replace(/(^-+|-+$)/g, ''); -const sanitizeMarkdown = (markdown: string, purify: typeof DOMPurify | null): string => { +const sanitizeMarkdown = (markdown: string): string => { const html = marked.parse(markdown || '', { async: false }) as string; - return purify ? purify.sanitize(html) : html; + return typeof window !== 'undefined' ? DOMPurify.sanitize(html) : html; }; const GlossaryTable: React.FC = () => { @@ -40,8 +41,6 @@ const GlossaryTable: React.FC = () => { const [textQuery, setTextQuery] = useState(''); const [activeSlug, setActiveSlug] = useState(''); - const purify = useMemo(() => (typeof window === 'undefined' ? null : DOMPurify), []); - const { entries, aliasToCanonicalSlug } = useMemo(() => { const glossaryItems = glossaryData as GlossaryItem[]; const termSet = new Set(glossaryItems.map((item) => item.term)); @@ -52,6 +51,7 @@ const GlossaryTable: React.FC = () => { term: item.term, abbreviation: item.abbreviation, definition: item.definition, + definitionHtml: sanitizeMarkdown(item.definition), canonicalTerm: item.term, isAlias: false, slug, @@ -68,6 +68,7 @@ const GlossaryTable: React.FC = () => { term: alias, abbreviation: '', definition: `See ${item.term}`, + definitionHtml: '', // Alias entries don't need HTML since they use a link canonicalTerm: item.term, isAlias: true, slug: slugify(alias), @@ -202,7 +203,6 @@ const GlossaryTable: React.FC = () => { {filteredEntries.map((entry) => { - const definitionHtml = sanitizeMarkdown(entry.definition, purify); const handleClick = () => focusEntry(entry.targetSlug, entry.canonicalTerm); return ( @@ -245,7 +245,7 @@ const GlossaryTable: React.FC = () => { <>
{entry.abbreviation ? ( diff --git a/website/src/components/Quiz/quizComponents.ts b/website/src/components/Quiz/quizComponents.ts index 21b28d0..c2380a7 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: 12/5/2025, 1:04:36 PM +* Generated on: 12/7/2025, 12:57:51 PM */ export interface QuizPage { From c5ed31c34e9fc47a90f0e9951e30a00652e7a536 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rene=CC=81?= Date: Sun, 7 Dec 2025 14:23:48 +0100 Subject: [PATCH 11/12] improved outline in dark mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: René --- website/src/components/Term.module.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/website/src/components/Term.module.css b/website/src/components/Term.module.css index 34010b7..9b9fe19 100644 --- a/website/src/components/Term.module.css +++ b/website/src/components/Term.module.css @@ -2,7 +2,7 @@ position: relative; cursor: help; background: var(--ifm-background-surface-color); - border: 0.1rem solid var(--ifm-color-emphasis-300) !important; + border: 0.1rem solid var(--ifm-color-emphasis-200) !important; border-radius: var(--ifm-code-border-radius) !important; padding: 0 var(--ifm-code-padding-horizontal); vertical-align: middle; From d648e8a81b9790ba8bee9f324540e1a9b0e4c975 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9?= <41592183+Snooz82@users.noreply.github.com> Date: Sun, 7 Dec 2025 14:27:10 +0100 Subject: [PATCH 12/12] Update website/src/components/Term.tsx Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> --- website/src/components/Term.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/website/src/components/Term.tsx b/website/src/components/Term.tsx index 6459378..562f0f7 100644 --- a/website/src/components/Term.tsx +++ b/website/src/components/Term.tsx @@ -122,7 +122,10 @@ export default function Term({ components={{ p: ({node: _node, ...props}) =>
, a: ({node: _node, href, ...props}) => { - const resolvedHref = href && href.startsWith("/") ? `${baseUrl}${href}` : href; + const resolvedHref = + href && href.startsWith("/") && !href.startsWith(baseUrl) + ? `${baseUrl}${href}` + : href; return (