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.
Files changed (52) hide show
  1. {mops-3.2.0 → mops-3.2.1}/PKG-INFO +1 -1
  2. {mops-3.2.0 → mops-3.2.1}/mops/__init__.py +1 -1
  3. {mops-3.2.0 → mops-3.2.1}/mops/js_scripts.py +1 -1
  4. {mops-3.2.0 → mops-3.2.1}/mops/mixins/internal_mixin.py +0 -7
  5. {mops-3.2.0 → mops-3.2.1}/mops/mixins/objects/locator_type.py +14 -0
  6. {mops-3.2.0 → mops-3.2.1}/mops/selenium/driver/web_driver.py +8 -5
  7. {mops-3.2.0 → mops-3.2.1}/mops/utils/selector_synchronizer.py +19 -11
  8. {mops-3.2.0 → mops-3.2.1}/mops/visual_comparison.py +11 -2
  9. {mops-3.2.0 → mops-3.2.1}/mops.egg-info/PKG-INFO +1 -1
  10. {mops-3.2.0 → mops-3.2.1}/README.md +0 -0
  11. {mops-3.2.0 → mops-3.2.1}/mops/abstraction/driver_wrapper_abc.py +0 -0
  12. {mops-3.2.0 → mops-3.2.1}/mops/abstraction/element_abc.py +0 -0
  13. {mops-3.2.0 → mops-3.2.1}/mops/abstraction/mixin_abc.py +0 -0
  14. {mops-3.2.0 → mops-3.2.1}/mops/abstraction/page_abc.py +0 -0
  15. {mops-3.2.0 → mops-3.2.1}/mops/base/driver_wrapper.py +0 -0
  16. {mops-3.2.0 → mops-3.2.1}/mops/base/element.py +0 -0
  17. {mops-3.2.0 → mops-3.2.1}/mops/base/group.py +0 -0
  18. {mops-3.2.0 → mops-3.2.1}/mops/base/page.py +0 -0
  19. {mops-3.2.0 → mops-3.2.1}/mops/exceptions.py +0 -0
  20. {mops-3.2.0 → mops-3.2.1}/mops/keyboard_keys.py +0 -0
  21. {mops-3.2.0 → mops-3.2.1}/mops/mixins/driver_mixin.py +0 -0
  22. {mops-3.2.0 → mops-3.2.1}/mops/mixins/native_context.py +0 -0
  23. {mops-3.2.0 → mops-3.2.1}/mops/mixins/objects/box.py +0 -0
  24. {mops-3.2.0 → mops-3.2.1}/mops/mixins/objects/driver.py +0 -0
  25. {mops-3.2.0 → mops-3.2.1}/mops/mixins/objects/location.py +0 -0
  26. {mops-3.2.0 → mops-3.2.1}/mops/mixins/objects/locator.py +0 -0
  27. {mops-3.2.0 → mops-3.2.1}/mops/mixins/objects/scrolls.py +0 -0
  28. {mops-3.2.0 → mops-3.2.1}/mops/mixins/objects/size.py +0 -0
  29. {mops-3.2.0 → mops-3.2.1}/mops/mixins/objects/wait_result.py +0 -0
  30. {mops-3.2.0 → mops-3.2.1}/mops/playwright/play_driver.py +0 -0
  31. {mops-3.2.0 → mops-3.2.1}/mops/playwright/play_element.py +0 -0
  32. {mops-3.2.0 → mops-3.2.1}/mops/playwright/play_page.py +0 -0
  33. {mops-3.2.0 → mops-3.2.1}/mops/selenium/core/core_driver.py +0 -0
  34. {mops-3.2.0 → mops-3.2.1}/mops/selenium/core/core_element.py +0 -0
  35. {mops-3.2.0 → mops-3.2.1}/mops/selenium/core/core_page.py +0 -0
  36. {mops-3.2.0 → mops-3.2.1}/mops/selenium/driver/mobile_driver.py +0 -0
  37. {mops-3.2.0 → mops-3.2.1}/mops/selenium/elements/mobile_element.py +0 -0
  38. {mops-3.2.0 → mops-3.2.1}/mops/selenium/elements/web_element.py +0 -0
  39. {mops-3.2.0 → mops-3.2.1}/mops/selenium/pages/mobile_page.py +0 -0
  40. {mops-3.2.0 → mops-3.2.1}/mops/selenium/pages/web_page.py +0 -0
  41. {mops-3.2.0 → mops-3.2.1}/mops/selenium/sel_utils.py +0 -0
  42. {mops-3.2.0 → mops-3.2.1}/mops/shared_utils.py +0 -0
  43. {mops-3.2.0 → mops-3.2.1}/mops/utils/decorators.py +0 -0
  44. {mops-3.2.0 → mops-3.2.1}/mops/utils/internal_utils.py +0 -0
  45. {mops-3.2.0 → mops-3.2.1}/mops/utils/logs.py +0 -0
  46. {mops-3.2.0 → mops-3.2.1}/mops/utils/previous_object_driver.py +0 -0
  47. {mops-3.2.0 → mops-3.2.1}/mops.egg-info/SOURCES.txt +0 -0
  48. {mops-3.2.0 → mops-3.2.1}/mops.egg-info/dependency_links.txt +0 -0
  49. {mops-3.2.0 → mops-3.2.1}/mops.egg-info/requires.txt +0 -0
  50. {mops-3.2.0 → mops-3.2.1}/mops.egg-info/top_level.txt +0 -0
  51. {mops-3.2.0 → mops-3.2.1}/pyproject.toml +0 -0
  52. {mops-3.2.0 → mops-3.2.1}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mops
3
- Version: 3.2.0
3
+ Version: 3.2.1
4
4
  Summary: Wrapper of Selenium, Appium and Playwright with single API
5
5
  Author-email: Podolian Vladimir <vladimir.podolyan64@gmail.com>
6
6
  License: MIT
@@ -1,2 +1,2 @@
1
- __version__ = '3.2.0'
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
- outer_width, outer_height = astuple(self.get_window_size())
36
- inner_width, inner_height = astuple(self.get_inner_window_size())
35
+ width, height = astuple(size)
37
36
 
38
- width_diff = outer_width - inner_width
39
- height_diff = outer_height - inner_height
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
- self.driver.set_window_size(size.width + width_diff, size.height + height_diff)
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[0:2]};"
323
- f"\nActual: {output_image.shape[0:2]}.") from None
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]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: mops
3
- Version: 3.2.0
3
+ Version: 3.2.1
4
4
  Summary: Wrapper of Selenium, Appium and Playwright with single API
5
5
  Author-email: Podolian Vladimir <vladimir.podolyan64@gmail.com>
6
6
  License: MIT
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