mops 3.2.0__tar.gz → 3.2.1__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mops-3.2.0 → mops-3.2.1}/PKG-INFO +1 -1
- {mops-3.2.0 → mops-3.2.1}/mops/__init__.py +1 -1
- {mops-3.2.0 → mops-3.2.1}/mops/js_scripts.py +1 -1
- {mops-3.2.0 → mops-3.2.1}/mops/mixins/internal_mixin.py +0 -7
- {mops-3.2.0 → mops-3.2.1}/mops/mixins/objects/locator_type.py +14 -0
- {mops-3.2.0 → mops-3.2.1}/mops/selenium/driver/web_driver.py +8 -5
- {mops-3.2.0 → mops-3.2.1}/mops/utils/selector_synchronizer.py +19 -11
- {mops-3.2.0 → mops-3.2.1}/mops/visual_comparison.py +11 -2
- {mops-3.2.0 → mops-3.2.1}/mops.egg-info/PKG-INFO +1 -1
- {mops-3.2.0 → mops-3.2.1}/README.md +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/abstraction/driver_wrapper_abc.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/abstraction/element_abc.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/abstraction/mixin_abc.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/abstraction/page_abc.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/base/driver_wrapper.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/base/element.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/base/group.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/base/page.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/exceptions.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/keyboard_keys.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/mixins/driver_mixin.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/mixins/native_context.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/mixins/objects/box.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/mixins/objects/driver.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/mixins/objects/location.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/mixins/objects/locator.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/mixins/objects/scrolls.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/mixins/objects/size.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/mixins/objects/wait_result.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/playwright/play_driver.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/playwright/play_element.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/playwright/play_page.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/selenium/core/core_driver.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/selenium/core/core_element.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/selenium/core/core_page.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/selenium/driver/mobile_driver.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/selenium/elements/mobile_element.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/selenium/elements/web_element.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/selenium/pages/mobile_page.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/selenium/pages/web_page.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/selenium/sel_utils.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/shared_utils.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/utils/decorators.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/utils/internal_utils.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/utils/logs.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops/utils/previous_object_driver.py +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops.egg-info/SOURCES.txt +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops.egg-info/dependency_links.txt +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops.egg-info/requires.txt +0 -0
- {mops-3.2.0 → mops-3.2.1}/mops.egg-info/top_level.txt +0 -0
- {mops-3.2.0 → mops-3.2.1}/pyproject.toml +0 -0
- {mops-3.2.0 → mops-3.2.1}/setup.cfg +0 -0
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
__version__ = '3.2.
|
|
1
|
+
__version__ = '3.2.1'
|
|
2
2
|
__project_name__ = 'mops'
|
|
@@ -46,7 +46,7 @@ function appendElement(given_obj) {
|
|
|
46
46
|
const driverWrapperObj = document.createElement("div");
|
|
47
47
|
|
|
48
48
|
driverWrapperObj.style.zIndex = 9999999;
|
|
49
|
-
driverWrapperObj.setAttribute("class", "driver-wrapper-comparison-support-element");
|
|
49
|
+
driverWrapperObj.setAttribute("class", "driver-wrapper-visual-comparison-support-element");
|
|
50
50
|
driverWrapperObj.style.backgroundColor = "#000";
|
|
51
51
|
|
|
52
52
|
// Determine position type based on scroll position
|
|
@@ -3,19 +3,12 @@ from __future__ import annotations
|
|
|
3
3
|
from functools import lru_cache
|
|
4
4
|
from typing import Any
|
|
5
5
|
|
|
6
|
-
from appium.webdriver.common.appiumby import AppiumBy
|
|
7
|
-
|
|
8
6
|
from mops.utils.internal_utils import (
|
|
9
7
|
get_child_elements_with_names,
|
|
10
|
-
get_child_elements,
|
|
11
8
|
get_all_attributes_from_object,
|
|
12
9
|
)
|
|
13
10
|
|
|
14
11
|
|
|
15
|
-
all_locator_types = get_child_elements(AppiumBy, str)
|
|
16
|
-
available_kwarg_keys = ('desktop', 'mobile', 'ios', 'android')
|
|
17
|
-
|
|
18
|
-
|
|
19
12
|
def get_element_info(element: Any, label: str = 'Selector=') -> str:
|
|
20
13
|
"""
|
|
21
14
|
Get element selector information with parent object selector if it exists
|
|
@@ -21,8 +21,22 @@ class LocatorType:
|
|
|
21
21
|
For better readability, you can use this class with the following syntax:
|
|
22
22
|
|
|
23
23
|
- :obj:`Element(f'{LocatorType.XPATH}=//*[@class="class-name"]')`
|
|
24
|
+
- :obj:`Element(f'{LocatorType.ANDROID_UIAUTOMATOR}=//*[@class="class-name"]')`
|
|
24
25
|
"""
|
|
25
26
|
CSS: str = 'css'
|
|
26
27
|
XPATH: str = 'xpath'
|
|
27
28
|
ID: str = 'id'
|
|
28
29
|
TEXT: str = 'text'
|
|
30
|
+
|
|
31
|
+
# Appium mobile native context
|
|
32
|
+
IOS_PREDICATE: str = '-ios predicate string'
|
|
33
|
+
IOS_UIAUTOMATION: str = '-ios uiautomation'
|
|
34
|
+
IOS_CLASS_CHAIN: str = '-ios class chain'
|
|
35
|
+
ANDROID_UIAUTOMATOR: str = '-android uiautomator'
|
|
36
|
+
ANDROID_VIEWTAG: str = '-android viewtag'
|
|
37
|
+
ANDROID_DATA_MATCHER: str = '-android datamatcher'
|
|
38
|
+
ANDROID_VIEW_MATCHER: str = '-android viewmatcher'
|
|
39
|
+
WINDOWS_UI_AUTOMATION: str = '-windows uiautomation'
|
|
40
|
+
ACCESSIBILITY_ID: str = 'accessibility id'
|
|
41
|
+
IMAGE: str = '-image'
|
|
42
|
+
CUSTOM: str = '-custom'
|
|
@@ -32,13 +32,16 @@ class WebDriver(CoreDriver):
|
|
|
32
32
|
:param size: The desired inner window size as a :class:`.Size` object.
|
|
33
33
|
:return: The current instance of :obj:`.WebDriver`.
|
|
34
34
|
"""
|
|
35
|
-
|
|
36
|
-
inner_width, inner_height = astuple(self.get_inner_window_size())
|
|
35
|
+
width, height = astuple(size)
|
|
37
36
|
|
|
38
|
-
|
|
39
|
-
|
|
37
|
+
if self.is_desktop:
|
|
38
|
+
outer_width, outer_height = astuple(self.get_window_size())
|
|
39
|
+
inner_width, inner_height = astuple(self.get_inner_window_size())
|
|
40
40
|
|
|
41
|
-
|
|
41
|
+
width += outer_width - inner_width
|
|
42
|
+
height += outer_height - inner_height
|
|
43
|
+
|
|
44
|
+
self.driver.set_window_size(width, height)
|
|
42
45
|
return self
|
|
43
46
|
|
|
44
47
|
def get_all_tabs(self) -> List[str]:
|
|
@@ -15,6 +15,19 @@ DEFAULT_MATCH = (f"{LocatorType.XPATH}=", f"{LocatorType.ID}=", f"{LocatorType.C
|
|
|
15
15
|
XPATH_MATCH = ("/", "./", "(/")
|
|
16
16
|
CSS_MATCH = ("#", ".")
|
|
17
17
|
CSS_REGEXP = r"[#.\[\]=]"
|
|
18
|
+
APPIUM_LOCATOR_TYPES = (
|
|
19
|
+
f'{LocatorType.IOS_PREDICATE}=',
|
|
20
|
+
f'{LocatorType.IOS_UIAUTOMATION}=',
|
|
21
|
+
f'{LocatorType.IOS_CLASS_CHAIN}=',
|
|
22
|
+
f'{LocatorType.ANDROID_UIAUTOMATOR}=',
|
|
23
|
+
f'{LocatorType.ANDROID_VIEWTAG}=',
|
|
24
|
+
f'{LocatorType.ANDROID_DATA_MATCHER}=',
|
|
25
|
+
f'{LocatorType.ANDROID_VIEW_MATCHER}=',
|
|
26
|
+
f'{LocatorType.WINDOWS_UI_AUTOMATION}=',
|
|
27
|
+
f'{LocatorType.ACCESSIBILITY_ID}=',
|
|
28
|
+
f'{LocatorType.IMAGE}=',
|
|
29
|
+
f'{LocatorType.CUSTOM}=',
|
|
30
|
+
)
|
|
18
31
|
|
|
19
32
|
|
|
20
33
|
def get_platform_locator(obj: Any):
|
|
@@ -89,11 +102,6 @@ def set_selenium_selector(obj: Any):
|
|
|
89
102
|
obj.locator_type = By.CSS_SELECTOR
|
|
90
103
|
obj.log_locator = f'{LocatorType.CSS}={locator}'
|
|
91
104
|
|
|
92
|
-
elif " " in locator:
|
|
93
|
-
obj.locator = f'//*[contains(text(), "{locator}")]'
|
|
94
|
-
obj.locator_type = By.XPATH
|
|
95
|
-
obj.log_locator = f'{LocatorType.XPATH}={obj.locator}'
|
|
96
|
-
|
|
97
105
|
# Default to ID if nothing else matches
|
|
98
106
|
|
|
99
107
|
else:
|
|
@@ -127,9 +135,6 @@ def set_playwright_locator(obj: Any):
|
|
|
127
135
|
elif locator in all_tags or all(tag in all_tags for tag in locator.split()):
|
|
128
136
|
obj.locator_type = LocatorType.CSS
|
|
129
137
|
|
|
130
|
-
elif " " in locator:
|
|
131
|
-
obj.locator_type = LocatorType.TEXT
|
|
132
|
-
|
|
133
138
|
# Default to ID if nothing else matches
|
|
134
139
|
|
|
135
140
|
else:
|
|
@@ -147,8 +152,11 @@ def set_appium_selector(obj: Any):
|
|
|
147
152
|
|
|
148
153
|
locator = obj.locator.strip()
|
|
149
154
|
|
|
150
|
-
# Mobile com.android selector
|
|
151
|
-
|
|
152
|
-
if ':id' in locator:
|
|
155
|
+
if ':id/' in locator: # Mobile com.android selector
|
|
153
156
|
obj.locator_type = By.CSS_SELECTOR
|
|
154
157
|
obj.log_locator = f'{LocatorType.ID}={locator}'
|
|
158
|
+
elif locator.startswith(APPIUM_LOCATOR_TYPES):
|
|
159
|
+
partition = locator.partition('=')
|
|
160
|
+
obj.locator_type = partition[0]
|
|
161
|
+
obj.locator = partition[-1]
|
|
162
|
+
obj.log_locator = locator
|
|
@@ -319,8 +319,8 @@ class VisualComparison:
|
|
|
319
319
|
scaled_image = cv2.resize(output_image, (width, height))
|
|
320
320
|
cv2.imwrite(diff_file, scaled_image)
|
|
321
321
|
raise AssertionError(f"↓\nImage size (width, height) is not same for '{self.screenshot_name}':"
|
|
322
|
-
f"\nExpected: {reference_image.shape
|
|
323
|
-
f"\nActual: {output_image.shape
|
|
322
|
+
f"\nExpected: {self._get_image_size_from_shape(reference_image.shape)};"
|
|
323
|
+
f"\nActual: {self._get_image_size_from_shape(output_image.shape)}.") from None
|
|
324
324
|
|
|
325
325
|
diff, actual_threshold = self._get_difference(reference_image, output_image, threshold)
|
|
326
326
|
is_different = actual_threshold > threshold
|
|
@@ -503,3 +503,12 @@ class VisualComparison:
|
|
|
503
503
|
:return: test_screenshot__data___name -> test_screenshot_data_name
|
|
504
504
|
"""
|
|
505
505
|
return re.sub(r'_{2,}', '_', text)
|
|
506
|
+
|
|
507
|
+
def _get_image_size_from_shape(self, shape: tuple) -> tuple:
|
|
508
|
+
"""
|
|
509
|
+
Get image size (width, height) from shape
|
|
510
|
+
|
|
511
|
+
:param shape: shape tuple from numpy.ndarray
|
|
512
|
+
:return: (width, height)
|
|
513
|
+
"""
|
|
514
|
+
return shape[1], shape[0]
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|