|
15 | 15 | """This module contains models representing Robot Framework test items.""" |
16 | 16 |
|
17 | 17 | import os |
18 | | -from typing import Any, Dict, List, Optional, Union |
| 18 | +import re |
| 19 | +from abc import ABC, abstractmethod |
| 20 | +from typing import Any, Callable, Dict, List, Optional, Union |
19 | 21 |
|
20 | 22 | from reportportal_client.helpers import gen_attributes |
21 | 23 |
|
22 | | -from robotframework_reportportal.helpers import robot_markup_to_markdown |
| 24 | +from robotframework_reportportal.helpers import match_pattern, robot_markup_to_markdown, translate_glob_to_regex |
23 | 25 |
|
24 | 26 | TEST_CASE_ID_SIGN = "test_case_id:" |
25 | 27 |
|
@@ -332,3 +334,63 @@ def update(self, attributes: Dict[str, Any]) -> "Test": |
332 | 334 | self.message = attributes.get("message") |
333 | 335 | self.status = attributes.get("status") |
334 | 336 | return self |
| 337 | + |
| 338 | + |
| 339 | +class KeywordMatch(ABC): |
| 340 | + """Base class for keyword matchers.""" |
| 341 | + |
| 342 | + @abstractmethod |
| 343 | + def match(self, kw: Keyword) -> bool: |
| 344 | + """Check if the keyword matches the criteria.""" |
| 345 | + |
| 346 | + |
| 347 | +class KeywordEqual(KeywordMatch): |
| 348 | + """Match keyword based on a predicate.""" |
| 349 | + |
| 350 | + predicate: Callable[[Keyword], bool] |
| 351 | + |
| 352 | + def __init__(self, predicate: Callable[[Keyword], bool] = None) -> None: |
| 353 | + """Initialize the matcher with the predicate.""" |
| 354 | + self.predicate = predicate |
| 355 | + |
| 356 | + def match(self, kw: Keyword) -> bool: |
| 357 | + """Check if the keyword matches the criteria.""" |
| 358 | + return self.predicate(kw) |
| 359 | + |
| 360 | + |
| 361 | +class KeywordNameMatch(KeywordEqual): |
| 362 | + """Match keyword based on the name pattern.""" |
| 363 | + |
| 364 | + def __init__(self, pattern: Optional[str]) -> None: |
| 365 | + """Initialize the matcher with the pattern.""" |
| 366 | + super().__init__(lambda kw: match_pattern(pattern, kw.name)) |
| 367 | + |
| 368 | + |
| 369 | +class KeywordTypeEqual(KeywordEqual): |
| 370 | + """Match keyword based on the type.""" |
| 371 | + |
| 372 | + def __init__(self, expected_value: Optional[str]) -> None: |
| 373 | + """Initialize the matcher with the expected value.""" |
| 374 | + super().__init__(lambda kw: kw.keyword_type == expected_value) |
| 375 | + |
| 376 | + |
| 377 | +class KeywordTagMatch(KeywordMatch): |
| 378 | + """Match keyword based on the tag pattern.""" |
| 379 | + |
| 380 | + pattern: Optional[re.Pattern] |
| 381 | + |
| 382 | + def __init__(self, pattern: Optional[str]) -> None: |
| 383 | + """Initialize the matcher with the pattern.""" |
| 384 | + self.pattern = translate_glob_to_regex(pattern) |
| 385 | + |
| 386 | + def match(self, kw: Keyword) -> bool: |
| 387 | + """Check if the keyword matches the criteria.""" |
| 388 | + return next((True for t in kw.tags if match_pattern(self.pattern, t)), False) |
| 389 | + |
| 390 | + |
| 391 | +class KeywordStatusEqual(KeywordEqual): |
| 392 | + """Match keyword based on the status.""" |
| 393 | + |
| 394 | + def __init__(self, status: str) -> None: |
| 395 | + """Initialize the matcher with the status.""" |
| 396 | + super().__init__(lambda kw: kw.status == status) |
0 commit comments