Skip to content

Commit 305bdcb

Browse files
Repr/selector tests and docs
1 parent 28b3375 commit 305bdcb

File tree

8 files changed

+101
-21
lines changed

8 files changed

+101
-21
lines changed

docs/source/kitchen_sink/index.md

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55
hidden:
66
---
77
8-
size
9-
location
8+
locator
9+
locator_type
1010
driver_container
11+
size
1112
box
12-
locator
13+
location
1314
scrolls
1415
```
1516

@@ -22,9 +23,10 @@ blocks for common operations, data structures, and utilities.
2223

2324
### Available Components
2425

25-
- {doc}`Size Dataclass <./size>`
26-
- {doc}`Location Dataclass <./location>`
26+
- {doc}`Locator Dataclass <./locator>`
27+
- {doc}`Locator Type Constants <./locator_type>`
2728
- {doc}`Driver Dataclass <./driver_container>`
29+
- {doc}`Size Dataclass <./size>`
2830
- {doc}`Box Dataclass <./box>`
29-
- {doc}`Locator Dataclass <./locator>`
31+
- {doc}`Location Dataclass <./location>`
3032
- {doc}`Scrolls Constants <./scrolls>`
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# Locator Type Constants
2+
3+
```{eval-rst}
4+
.. autoclass:: mops.mixins.objects.locator_type.LocatorType
5+
:undoc-members:
6+
:inherited-members:
7+
```

mops/base/element.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def __init__(
9090
9191
If no driver is available, initialization is skipped and will be handled later in a Page or Group.
9292
93-
:param locator: The element's locator
93+
:param locator: The element's locator. `.LocatorType` is optional.
9494
:type locator: typing.Union[Locator, str]
9595
:param name: The name of the element, used for logging and identification purposes.
9696
:type name: str

mops/base/group.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def __init__(
5050
with specific methods to manage child elements, locator handling, and initialization
5151
with respect to the driver.
5252
53-
:param locator: The anchor locator for the group
53+
:param locator: The anchor locator for the group. `.LocatorType` is optional.
5454
:type locator: typing.Union[Locator, str]
5555
:param name: The name of the group, used for logging and identification purposes.
5656
:type name: str

mops/base/page.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def __init__(
6262
"""
6363
Initializes a Page based on the current driver.
6464
65-
:param locator: The anchor locator of the page
65+
:param locator: The anchor locator of the page. `.LocatorType` is optional.
6666
:type locator: typing.Union[Locator, str]
6767
:param name: The name of the page, used for logging and identification purposes.
6868
:type name: str

mops/mixins/objects/locator_type.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
class LocatorType:
2+
"""
3+
A container for locator types.
4+
5+
This class standardizes the locator types used in the Mops framework, ensuring
6+
consistency and clarity when locating elements within web pages.
7+
8+
.. note::
9+
You can specify a locator type along with your locator using the following syntax:
10+
11+
- :obj:`Element('xpath=//*[@class="class-attribute"]')`
12+
- :obj:`Element('css=//*[@class="class-attribute"]')`
13+
- :obj:`Element('text=some text')`
14+
- :obj:`Element('id=id-without-spaces')`
15+
16+
The same applies to the :class:`.Locator` object:
17+
18+
- :obj:`Element(Locator(ios='xpath=//*[@class, "ios-specific"]'))`
19+
20+
.. note::
21+
For better readability, you can use this class with the following syntax:
22+
23+
- :obj:`Element(f'{LocatorType.XPATH}=//*[@class="class-attribute"]')`
24+
"""
25+
CSS: str = 'css'
26+
XPATH: str = 'xpath'
27+
ID: str = 'id'
28+
TEXT: str = 'text'

mops/utils/selector_synchronizer.py

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,17 @@
11
from __future__ import annotations
22

33
import re
4-
from dataclasses import dataclass
54
from typing import Any, Union
65

76
from selenium.webdriver.common.by import By
87

98
from mops.exceptions import InvalidLocatorException
109
from mops.mixins.objects.locator import Locator
10+
from mops.mixins.objects.locator_type import LocatorType
1111
from mops.utils.internal_utils import all_tags
1212

1313

14+
DEFAULT_MATCH = (f"{LocatorType.XPATH}=", f"{LocatorType.ID}=", f"{LocatorType.CSS}=", f"{LocatorType.TEXT}=")
1415
XPATH_MATCH = ("/", "./", "(/")
1516
CSS_MATCH = ("#", ".")
1617
CSS_REGEXP = r"[#.\[\]=]"
@@ -47,14 +48,6 @@ def get_platform_locator(obj: Any):
4748
return locator
4849

4950

50-
@dataclass
51-
class LocatorType:
52-
CSS = 'css'
53-
XPATH = 'xpath'
54-
ID = 'id'
55-
TEXT = 'text'
56-
57-
5851
def set_selenium_selector(obj: Any):
5952
"""
6053
Sets selenium locator & locator type
@@ -110,9 +103,6 @@ def set_selenium_selector(obj: Any):
110103
obj.log_locator = f'{LocatorType.ID}={locator}'
111104

112105

113-
DEFAULT_MATCH = (f"{LocatorType.XPATH}=", f"{LocatorType.ID}=", f"{LocatorType.CSS}=", f"{LocatorType.TEXT}=")
114-
115-
116106
def set_playwright_locator(obj: Any):
117107
"""
118108
Sets playwright locator & locator type
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
from types import SimpleNamespace
2+
3+
import pytest
4+
from selenium.webdriver.common.by import By
5+
6+
from mops.utils.selector_synchronizer import set_selenium_selector, set_playwright_locator
7+
8+
9+
@pytest.mark.parametrize(
10+
"locator_input, expected_locator, expected_locator_type, expected_log_locator",
11+
[
12+
("xpath=//div", "//div", By.XPATH, "xpath=//div"),
13+
("text=Hello", '//*[contains(text(), "Hello")]', By.XPATH, "text=Hello"),
14+
("css=.class", ".class", By.CSS_SELECTOR, "css=.class"),
15+
("id=my_id", '[id="my_id"]', By.CSS_SELECTOR, "id=my_id"),
16+
("/html/body/div", "/html/body/div", By.XPATH, "xpath=/html/body/div"),
17+
("#my_element", "#my_element", By.CSS_SELECTOR, "css=#my_element"),
18+
("button", "button", By.CSS_SELECTOR, "css=button"),
19+
("div span", "div span", By.CSS_SELECTOR, "css=div span"),
20+
("Some text", '//*[contains(text(), "Some text")]', By.XPATH, "xpath=Some text"),
21+
("[href='/some/url']", "[href='/some/url']", By.CSS_SELECTOR, "css=[href='/some/url']"),
22+
],
23+
)
24+
def test_set_selenium_selector(locator_input, expected_locator, expected_locator_type, expected_log_locator):
25+
mock_obj = SimpleNamespace()
26+
mock_obj.locator = locator_input
27+
set_selenium_selector(mock_obj)
28+
assert mock_obj.locator == expected_locator
29+
assert mock_obj.log_locator == expected_log_locator
30+
31+
32+
@pytest.mark.parametrize(
33+
"locator_input, expected_locator, expected_log_locator",
34+
[
35+
("xpath=//div", "xpath=//div", "xpath=//div"),
36+
("text=Hello", "text=Hello", "text=Hello"),
37+
("css=.class", "css=.class", "css=.class"),
38+
("id=my_id", "id=my_id", "id=my_id"),
39+
("/html/body/div", "xpath=/html/body/div", "xpath=/html/body/div"),
40+
("#my_element", "css=#my_element", "css=#my_element"),
41+
("button", "css=button", "css=button"),
42+
("div span", "text=div span", "text=div span"),
43+
("Some text", "text=Some text", "text=Some text"),
44+
("[href='/some/url']", "css=[href='/some/url']", "css=[href='/some/url']"),
45+
("", "id=", "id="),
46+
],
47+
)
48+
def test_set_playwright_locator(locator_input, expected_locator, expected_log_locator):
49+
mock_obj = SimpleNamespace()
50+
mock_obj.locator = locator_input
51+
set_playwright_locator(mock_obj)
52+
assert mock_obj.locator == expected_locator
53+
assert mock_obj.log_locator == expected_log_locator

0 commit comments

Comments
 (0)