Skip to content

Commit cbec970

Browse files
author
solomon.legodi
committed
Implement GlossaryTerm React component per reviewer feedback
- Created GlossaryTerm.tsx component with hover tooltips - Added GlossaryTerm.module.css for styling - Updated glossary linker to output component format - Uses placeholder system to prevent nested components - Excludes :term[] directives, code blocks, and existing links - Auto-adds import statements to modified files - ~412 glossary links across 31 files
1 parent dec3af7 commit cbec970

34 files changed

Lines changed: 459 additions & 267 deletions

tools/glossary_linker.py

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,23 @@ def _split_frontmatter(self, content: str) -> Tuple[str, str]:
212212

213213
return frontmatter, main_content
214214

215+
def _ensure_glossary_import(self, content: str) -> str:
216+
"""
217+
Ensure the GlossaryTerm import is present after frontmatter.
218+
Returns updated content with import if needed.
219+
"""
220+
import_statement = "import GlossaryTerm from '@site/src/components/Glossary/GlossaryTerm';\n\n"
221+
222+
# Check if import already exists
223+
if "import GlossaryTerm" in content:
224+
return content
225+
226+
# Split frontmatter and main content
227+
frontmatter, main_content = self._split_frontmatter(content)
228+
229+
# Insert import after frontmatter
230+
return frontmatter + import_statement + main_content
231+
215232
def _create_link_patterns(self, current_file: Path) -> List[Tuple]:
216233
"""
217234
Create regex patterns for finding and replacing glossary terms.
@@ -319,6 +336,8 @@ def process_markdown_file(self, file_path: Path, dry_run: bool = False) -> Dict:
319336
else:
320337
# Apply patterns to text sections only
321338
modified_content = section_content
339+
placeholders = {} # Store placeholders
340+
placeholder_counter = 0
322341

323342
# Process each pattern
324343
for pattern, canonical_term, slug, glossary_url in patterns:
@@ -332,13 +351,21 @@ def process_markdown_file(self, file_path: Path, dry_run: bool = False) -> Dict:
332351

333352
# Check if we've already linked this term (case-insensitive check)
334353
if matched_text.lower() not in already_linked:
335-
# Create link with MATCHED text (preserves original casing)
336-
replacement = f'[{matched_text}]({glossary_url}#{slug})'
354+
# Create GlossaryTerm component (preserves original casing)
355+
# Format: <GlossaryTerm term={"canonical term"}>matched text</GlossaryTerm>
356+
# Escape quotes in the term
357+
escaped_term = canonical_term.replace('\\', '\\\\').replace('"', '\\"')
358+
component = f'<GlossaryTerm term={{"{escaped_term}"}}>{matched_text}</GlossaryTerm>'
359+
360+
# Use a placeholder that won't match any pattern
361+
placeholder = f'___GLOSSARY_PLACEHOLDER_{placeholder_counter}___'
362+
placeholders[placeholder] = component
363+
placeholder_counter += 1
337364

338-
# Replace this specific occurrence
365+
# Replace with placeholder
339366
modified_content = (
340367
modified_content[:match.start(1)] +
341-
replacement +
368+
placeholder +
342369
modified_content[match.end(1):]
343370
)
344371

@@ -352,11 +379,19 @@ def process_markdown_file(self, file_path: Path, dry_run: bool = False) -> Dict:
352379
# Mark as linked (case-insensitive)
353380
already_linked.add(matched_text.lower())
354381

382+
# Replace all placeholders with actual components
383+
for placeholder, component in placeholders.items():
384+
modified_content = modified_content.replace(placeholder, component)
385+
355386
processed_sections.append(modified_content)
356387

357388
# Reconstruct content with frontmatter
358389
new_content = frontmatter + ''.join(processed_sections)
359390

391+
# Add GlossaryTerm import if terms were linked
392+
if stats['terms_linked'] > 0:
393+
new_content = self._ensure_glossary_import(new_content)
394+
360395
# Only write if content changed and not a dry run
361396
if new_content != original_content and not dry_run:
362397
with open(file_path, 'w', encoding='utf-8') as f:
@@ -425,8 +460,8 @@ def _split_content_sections(self, content: str) -> List[Tuple[str, str]]:
425460
sections.append(('lo_block', '\n'.join(lo_block) + '\n'))
426461
continue
427462

428-
# Check for inline code or existing links in the line
429-
if '`' in line or '[' in line:
463+
# Check for inline code, existing links, GlossaryTerm components, or :term[] directives in the line
464+
if '`' in line or '[' in line or '<GlossaryTerm' in line or ':term[' in line:
430465
# Split this line more carefully
431466
processed_line = self._process_line_with_special_content(line)
432467
sections.extend(processed_line)
@@ -441,14 +476,14 @@ def _split_content_sections(self, content: str) -> List[Tuple[str, str]]:
441476

442477
def _process_line_with_special_content(self, line: str) -> List[Tuple[str, str]]:
443478
"""
444-
Process a line that may contain inline code or existing links.
479+
Process a line that may contain inline code, existing links, GlossaryTerm components, or :term[] directives.
445480
Split it into linkable and non-linkable parts.
446481
"""
447482
sections = []
448483
current_pos = 0
449484

450-
# Pattern to find inline code (`...`) or existing links ([...](...)
451-
special_pattern = re.compile(r'(`[^`]+`|\[[^\]]+\]\([^\)]+\))')
485+
# Pattern to find inline code (`...`), existing links ([...](...) ), GlossaryTerm components, or :term[] directives
486+
special_pattern = re.compile(r'(`[^`]+`|\[[^\]]+\]\([^\)]+\)|<GlossaryTerm[^>]*>.*?</GlossaryTerm>|:term\[[^\]]+\](?:\{[^}]+\})?)')
452487

453488
for match in special_pattern.finditer(line):
454489
# Add text before the special content
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,6 @@
1+
import GlossaryTerm from '@site/src/components/Glossary/GlossaryTerm';
2+
13
# 1 Introduction to Robot Framework
24

3-
The upcoming chapters provide a concise overview of Robot Framework, including its core structure, use cases in test automation and [Robotic Process Automation](/docs/glossary#robotic-process-automation) (RPA), and key specification styles like [keyword](/docs/glossary#keyword)-driven and behavior-driven testing. You'll learn about its architecture, syntax, and how [test cases](/docs/glossary#[test](/docs/glossary#test-case)-case) and [tasks](/docs/glossary#task) are organized. Additionally, the chapters explain the open-source licensing under Apache 2.0, the role of the [Robot Framework Foundation](/docs/glossary#robot-framework-foundation) in maintaining the ecosystem, and the foundational web resources available for further exploration and contributions.
5+
The upcoming chapters provide a concise overview of Robot Framework, including its core structure, use cases in <GlossaryTerm term={"Test Case"}>test</GlossaryTerm> automation and [Robotic Process Automation](/docs/glossary#robotic-process-automation) (RPA), and key specification styles like [keyword](/docs/glossary#keyword)-driven and behavior-driven testing. You'll learn about its architecture, syntax, and how [test cases](/docs/glossary#[test](/docs/glossary#test-case)-case) and [tasks](/docs/glossary#task) are organized. Additionally, the chapters explain the open-source licensing under Apache 2.0, the role of the [Robot Framework Foundation](/docs/glossary#robot-framework-foundation) in maintaining the ecosystem, and the foundational web resources available for further exploration and contributions.
6+

website/docs/chapter-01/01_purpose.md

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import GlossaryTerm from '@site/src/components/Glossary/GlossaryTerm';
2+
13
# 1.1 Purpose / Use Cases
24

35
::::lo[Learning Objectives]
@@ -35,13 +37,13 @@ Robot Framework is widely used at various levels of testing, primarily focusing
3537

3638
- **System Integration Testing**: Focuses on the interaction between the system under [test](/docs/glossary#test-case) and external services, as well as on the integration of multiple systems into a larger system, ensuring that all integrated components communicate and function together as expected.
3739

38-
- **Acceptance Testing**: Aims to validate that the system meets business requirements and is ready for deployment or release. This often includes different forms of acceptance testing (e.g., user acceptance, operational acceptance, regulatory acceptance) and is frequently written or conducted by end-users or stakeholders to confirm the system’s readiness for use. Acceptance tests, often defined by business stakeholders in approaches like Acceptance Test-Driven Development (ATDD), can be automated and executed earlier in the development process. This ensures that the solution aligns with business requirements from the start and provides immediate feedback, reducing costly changes later.
40+
- **Acceptance Testing**: Aims to validate that the system meets business requirements and is ready for deployment or release. This often includes different forms of <GlossaryTerm term={"Acceptance Testing"}>acceptance testing</GlossaryTerm> (e.g., user acceptance, operational acceptance, regulatory acceptance) and is frequently written or conducted by end-users or stakeholders to confirm the system’s readiness for use. Acceptance tests, often defined by business stakeholders in approaches like Acceptance <GlossaryTerm term={"Test Case"}>Test</GlossaryTerm>-Driven Development (ATDD), can be automated and executed earlier in the development process. This ensures that the solution aligns with business requirements from the start and provides immediate feedback, reducing costly changes later.
3941

4042
- **End-to-End Testing**: Verifies that a complete workflow or process within the system operates as intended, covering all interconnected subsystems, interfaces, and external components. [End-to-end tests](/docs/glossary#end-to-end-test) ensure the correct functioning of the application in real-world scenarios by simulating user interactions from start to finish.
4143

4244
Robot Framework's flexibility and support for external libraries make it an excellent tool for automating these comprehensive [test cases](/docs/glossary#test-case), ensuring seamless interaction between components and validating the system's behavior also in production or production-like conditions.
4345

44-
Robot Framework is typically not used for **component testing** nor **integration testing** because its primary strength lies in higher-level testing, such as system, acceptance, and end-to-end testing, where behavior-driven and keyword-based approaches excel. Component testing requires low-level, granular tests focusing on individual units of code, often necessitating direct interaction with the codebase, mocking, or stubbing, which are better handled by unit testing frameworks like JUnit, pytest, or NUnit. Similarly, integration testing at a low level often requires precise control over service interactions, such as API stubs or protocol-level testing, which may not align with Robot Framework's abstraction-oriented design. While Robot Framework can technically handle these cases through custom libraries, its overhead and design philosophy make it less efficient compared to tools specifically tailored for low-level and tightly scoped testing tasks.
46+
Robot Framework is typically not used for **component testing** nor **integration testing** because its primary strength lies in higher-level testing, such as system, acceptance, and end-to-end testing, where behavior-driven and <GlossaryTerm term={"Keyword"}>keyword</GlossaryTerm>-based approaches excel. Component testing requires low-level, granular tests focusing on individual units of code, often necessitating direct interaction with the codebase, mocking, or stubbing, which are better handled by unit testing frameworks like JUnit, pytest, or NUnit. Similarly, integration testing at a low level often requires precise control over service interactions, such as API stubs or protocol-level testing, which may not align with Robot Framework's abstraction-oriented design. While Robot Framework can technically handle these cases through custom libraries, its overhead and design philosophy make it less efficient compared to tools specifically tailored for low-level and tightly scoped testing <GlossaryTerm term={"Task"}>tasks</GlossaryTerm>.
4547

4648

4749
### 1.1.1.1 Synthetic Monitoring
@@ -55,12 +57,13 @@ Beyond traditional [test levels](/docs/glossary#test-level), **Synthetic Monitor
5557
[Robotic Process Automation](/docs/glossary#robotic-process-automation) (RPA) uses software bots to perform tasks and interactions normally performed by humans, without requiring changes to the underlying applications.
5658

5759
Robot Framework, with its keyword-driven approach, vast ecosystem of libraries, simplicity, and scalability, is widely adopted for [RPA](/docs/glossary#robotic-process-automation) tasks.
58-
Robot Framework allows users to automate most workflows using ready-made keyword libraries that provide a wide range of functionalities. These libraries can be combined and reused in user-defined [keywords](/docs/glossary#keyword), making automation simple and efficient. For custom functionalities or more complex tasks, Robot Framework also offers the flexibility to create custom keyword libraries using Python, enabling advanced use cases and seamless integration with unique systems.
60+
Robot Framework allows users to automate most workflows using ready-made <GlossaryTerm term={"Keyword Library"}>keyword libraries</GlossaryTerm> that provide a wide range of functionalities. These libraries can be combined and reused in user-defined [keywords](/docs/glossary#keyword), making automation simple and efficient. For custom functionalities or more complex tasks, Robot Framework also offers the flexibility to create custom keyword libraries using Python, enabling advanced use cases and seamless integration with unique systems.
5961

60-
Common use cases of RPA with Robot Framework include:
62+
Common use cases of <GlossaryTerm term={"Robotic Process Automation"}>RPA</GlossaryTerm> with Robot Framework include:
6163

6264
- **Data extraction and manipulation**: Automating data transfers and processing between systems.
6365
- **Task / Process automation**: Automating tasks such as form submissions, clicks, and file operations across web or desktop applications.
6466

6567

6668

69+

website/docs/chapter-01/02_architecture.md

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import GlossaryTerm from '@site/src/components/Glossary/GlossaryTerm';
2+
13
# 1.2 Architecture of Robot Framework
24

35
Robot Framework is an open-source automation framework that allows you to build [automation scripts](/docs/glossary#automation-script) for testing and [RPA](/docs/glossary#robotic-process-automation) (Robotic Process Automation).
@@ -19,22 +21,22 @@ Recall the layers of the Generic Test Automation Architecture (gTAA) and their c
1921

2022
::::
2123

22-
The **Generic Test Automation Architecture (gTAA)** described in the ISTQB "Certified Tester Advanced Level Test Automation Engineering" offers a structured approach to [test](/docs/glossary#test-case) automation, dividing it into different layers for a clear separation of concerns:
24+
The **Generic Test Automation Architecture (gTAA)** described in the ISTQB "Certified Tester Advanced Level <GlossaryTerm term={"Test Case"}>Test</GlossaryTerm> Automation Engineering" offers a structured approach to [test](/docs/glossary#test-case) automation, dividing it into different layers for a clear separation of concerns:
2325

24-
- **Definition Layer**: This layer contains the "[Test Data](/docs/glossary#test-data)" ([test cases](/docs/glossary#test-case), tasks, [resource files](/docs/glossary#resource-file) which include [user keywords](/docs/glossary#user-keyword) and variables).
25-
In Robot Framework, the test data is written using the defined syntax and contains keyword calls and [argument](/docs/glossary#argument) values that make the [test case](/docs/glossary#test-case) or [task](/docs/glossary#task) definitions structured in suites.
26+
- **Definition Layer**: This layer contains the "[Test Data](/docs/glossary#test-data)" ([test cases](/docs/glossary#test-case), <GlossaryTerm term={"Task"}>tasks</GlossaryTerm>, [resource files](/docs/glossary#resource-file) which include [user keywords](/docs/glossary#user-keyword) and variables).
27+
In Robot Framework, the <GlossaryTerm term={"Test Data"}>test data</GlossaryTerm> is written using the defined syntax and contains <GlossaryTerm term={"Keyword"}>keyword</GlossaryTerm> calls and [argument](/docs/glossary#argument) values that make the [test case](/docs/glossary#test-case) or [task](/docs/glossary#task) definitions structured in suites.
2628

2729
- **Execution Layer**: In Robot Framework, the [execution layer](/docs/glossary#execution-layer) consists of the framework itself, including its core components and APIs.
2830
It parses and interprets the test data syntax to build an [execution model](/docs/glossary#execution-model).
29-
The execution layer is responsible for processing this execution model to execute the library [keywords](/docs/glossary#keyword) with their argument values, logging results, and generating reports.
31+
The <GlossaryTerm term={"Execution Layer"}>execution layer</GlossaryTerm> is responsible for processing this <GlossaryTerm term={"Execution Model"}>execution model</GlossaryTerm> to execute the library [keywords](/docs/glossary#keyword) with their <GlossaryTerm term={"Argument"}>argument</GlossaryTerm> values, logging results, and generating reports.
3032

3133
- **Adaptation Layer**: This layer provides the connection between Robot Framework and the system under test (SUT).
3234
In Robot Framework, this is where the [keyword libraries](/docs/glossary#keyword-library), which contain code responsible for interacting with different technologies and interfaces,
3335
such as those for UI, API, database interactions, or others, are located.
34-
These keyword libraries enable interaction with different technologies and interfaces, ensuring the automation is flexible and adaptable to various environments.
36+
These <GlossaryTerm term={"Keyword Library"}>keyword libraries</GlossaryTerm> enable interaction with different technologies and interfaces, ensuring the automation is flexible and adaptable to various environments.
3537

3638
Editors/IDEs that offer support for Robot Framework's syntax are tools that support or integrate in these layers.
37-
When writing tests|tasks or keywords, the editor supports the [definition layer](/docs/glossary#definition-layer).
39+
When writing tests|tasks or <GlossaryTerm term={"Keyword"}>keywords</GlossaryTerm>, the editor supports the [definition layer](/docs/glossary#definition-layer).
3840
When executing or debugging tests|tasks, the editor supports the execution layer.
3941
When writing keywords in e.g. Python for keyword libraries, the editor supports the [adaptation layer](/docs/glossary#adaptation-layer).
4042
Therefore also other additional extensions of Robot Framework can be categorized into these layers.
@@ -54,7 +56,7 @@ Recall what is part of Robot Framework and what is not
5456
::::
5557

5658

57-
Robot Framework itself focuses primarily on **test|task execution**.
59+
Robot Framework itself focuses primarily on **test|<GlossaryTerm term={"Task"}>task</GlossaryTerm> execution**.
5860
It includes:
5961

6062
- A parser to read test|task data and build an execution model.
@@ -65,7 +67,7 @@ It includes:
6567

6668
However, Robot Framework **does not** include:
6769

68-
- Keyword libraries to control systems under test/RPA.
70+
- Keyword libraries to control systems under test/<GlossaryTerm term={"Robotic Process Automation"}>RPA</GlossaryTerm>.
6971

7072
Such as:
7173
- Web front-end automation libraries.
@@ -103,3 +105,4 @@ Robot Framework itself does not have any external dependencies, but additional t
103105

104106

105107

108+

0 commit comments

Comments
 (0)