Skip to content
This repository was archived by the owner on Aug 10, 2022. It is now read-only.

Commit f91fb07

Browse files
committed
Fix full page screenshot on mobile web
1 parent 626ba5f commit f91fb07

File tree

6 files changed

+64
-42
lines changed

6 files changed

+64
-42
lines changed

eyes_selenium/applitools/selenium/eyes_selenium_utils.py

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -100,14 +100,21 @@
100100
_RETRIES = 3
101101

102102

103-
def is_mobile_device(driver):
103+
def is_mobile_platform(driver):
104+
driver = get_underlying_driver(driver)
105+
if isinstance(driver, AppiumWebDriver):
106+
return True
107+
return is_mobile_web(driver) or is_mobile_app(driver)
108+
109+
110+
def is_mobile_web(driver):
104111
# type: (AnyWebDriver) -> bool
105112
"""
106113
Returns whether the platform running is a mobile device or not.
107114
108115
:return: True if the platform running the test is a mobile platform. False otherwise.
109116
"""
110-
is_mobile = """
117+
is_mobile_script = """
111118
if( navigator.userAgent.match(/Android/i) ||
112119
navigator.userAgent.match(/iPhone/i) ||
113120
navigator.userAgent.match(/iPad/i) ||
@@ -117,29 +124,31 @@ def is_mobile_device(driver):
117124
return false;
118125
}
119126
"""
120-
# TODO: Implement proper UserAgent handling
121-
driver = get_underlying_driver(driver)
122-
if isinstance(driver, AppiumWebDriver):
123-
return True
124-
125127
# if driver is selenium based
126128
platform_name = driver.desired_capabilities.get("platformName", "").lower()
127129
# platformName sometime have different names
128-
is_mobile_platform = "android" in platform_name or "ios" in platform_name
129-
if not is_mobile_platform:
130+
is_mobile = "android" in platform_name or "ios" in platform_name
131+
if not is_mobile:
130132
try:
131-
is_mobile_platform = driver.execute_script(is_mobile)
133+
is_mobile = driver.execute_script(is_mobile_script)
132134
except WebDriverException as e:
133135
logger.warning(
134-
"Got error during checking if current platform is mobile. "
136+
"Got error during checking if current platform is mobile web. "
135137
"\n\t {}".format(str(e))
136138
)
137-
if "Method is not implemented" in str(e):
138-
# potentially mobile app
139-
is_mobile_platform = True
140-
else:
141-
is_mobile_platform = False
142-
return is_mobile_platform
139+
is_mobile = False
140+
return is_mobile
141+
142+
143+
def is_mobile_app(driver):
144+
# TODO: check with hybrid mobile apps
145+
platform_name = driver.desired_capabilities.get("platformName", "").lower()
146+
# platformName sometime have different names
147+
is_mobile = "android" in platform_name or "ios" in platform_name
148+
app = driver.desired_capabilities.get("app", None)
149+
if is_mobile and app:
150+
return True
151+
return False
143152

144153

145154
def get_underlying_driver(driver):
@@ -210,7 +219,7 @@ def set_browser_size(driver, required_size):
210219
retries_left = _RETRIES
211220

212221
# set browser size for mobile devices isn't working
213-
if is_mobile_device(driver):
222+
if is_mobile_web(driver):
214223
return True
215224

216225
while True:
@@ -380,7 +389,7 @@ def timeout(timeout):
380389

381390

382391
def is_landscape_orientation(driver):
383-
if is_mobile_device(driver):
392+
if is_mobile_web(driver):
384393
# could be AppiumRemoteWebDriver
385394
appium_driver = get_underlying_driver(
386395
driver
@@ -453,7 +462,7 @@ def root_html():
453462
return driver.find_element_by_tag_name("html")
454463

455464
scroll_root_element = None
456-
if not driver.is_mobile_device():
465+
if not driver.is_mobile_app:
457466
if container is None:
458467
scroll_root_element = root_html()
459468
else:
@@ -479,6 +488,6 @@ def current_frame_scroll_root_element(driver):
479488
root_element = None
480489
if cur_frame:
481490
root_element = cur_frame.scroll_root_element
482-
if root_element is None and not driver.is_mobile_device():
491+
if root_element is None and not driver.is_mobile_app:
483492
root_element = driver.find_element_by_tag_name("html")
484493
return root_element

eyes_selenium/applitools/selenium/positioning.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ def __init__(self, driver, scroll_root_element):
5050

5151
def __enter__(self):
5252
# type: () -> SeleniumPositionProvider
53-
if self._driver.is_mobile_device():
53+
if self._driver.is_mobile_app:
5454
return self
5555
return super(SeleniumPositionProvider, self).__enter__()
5656

@@ -61,7 +61,7 @@ def __exit__(
6161
exc_tb, # type: Optional[Any]
6262
):
6363
# type: (...) -> Union[CSSTranslatePositionProvider, ScrollPositionProvider]
64-
if self._driver.is_mobile_device():
64+
if self._driver.is_mobile_app:
6565
return self
6666
return super(SeleniumPositionProvider, self).__exit__(exc_type, exc_val, exc_tb)
6767

@@ -71,7 +71,7 @@ def get_entire_size(self):
7171
:return: The entire size of the container which the position is relative to.
7272
"""
7373
try:
74-
if self._driver.is_mobile_device():
74+
if self._driver.is_mobile_app:
7575
width, height = self._driver.execute_script(
7676
self._JS_GET_CONTENT_ENTIRE_SIZE
7777
)
@@ -108,7 +108,7 @@ def set_position(self, location):
108108
logger.debug(
109109
"setting position of %s to %s" % (location, self._scroll_root_element)
110110
)
111-
if self._driver.is_mobile_device():
111+
if self._driver.is_mobile_web:
112112
scroll_command = "window.scrollTo({0}, {1})".format(location.x, location.y)
113113
self._driver.execute_script(scroll_command)
114114
self._last_set_position = location
@@ -139,7 +139,7 @@ def get_current_position(self):
139139
"""
140140
The scroll position of the current frame.
141141
"""
142-
if self._driver.is_mobile_device():
142+
if self._driver.is_mobile_web:
143143
x, y = self._driver.execute_script(
144144
self._JS_GET_CURRENT_SCROLL_POSITION, self._scroll_root_element
145145
)

eyes_selenium/applitools/selenium/selenium_eyes.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ def check(self, name, check_settings=None):
243243
)
244244
self._original_frame_chain = self.driver.frame_chain.clone()
245245

246-
if not self.driver.is_mobile_device():
246+
if not self.driver.is_mobile_web:
247247
# hide scrollbar for main window
248248
self._try_hide_scrollbars()
249249

@@ -294,7 +294,7 @@ def _check_result_flow(self, name, check_settings):
294294
result = self._check_frame_fluent(name, check_settings)
295295
else:
296296
logger.debug("default case")
297-
if not self.driver.is_mobile_device():
297+
if not self.driver.is_mobile_platform:
298298
# required to prevent cut line on the last stitched part of the
299299
# page on some browsers (like firefox).
300300
self.driver.switch_to.default_content()
@@ -499,7 +499,7 @@ def _set_viewport_size(self, size):
499499
# logger.info("Ignored (viewport size given explicitly)")
500500
# return None
501501

502-
if not self.driver.is_mobile_device():
502+
if not self.driver.is_mobile_platform:
503503
original_frame = self.driver.frame_chain.clone()
504504
self.driver.switch_to.default_content()
505505

@@ -525,7 +525,7 @@ def _environment(self):
525525
logger.info("No OS set, checking for mobile OS...")
526526
# Since in Python Appium driver is the same for Android and iOS,
527527
# we need to use the desired capabilities to figure this out.
528-
if eyes_selenium_utils.is_mobile_device(self._driver):
528+
if self._driver.is_mobile_platform:
529529
platform_name = self._driver.platform_name
530530
logger.info(platform_name + " detected")
531531
platform_version = self._driver.platform_version
@@ -668,7 +668,7 @@ def _try_hide_caret(self):
668668

669669
def _get_screenshot(self):
670670
with self._driver.switch_to.frames_and_back(self._original_frame_chain):
671-
if self.position_provider and not self.driver.is_mobile_device():
671+
if self.position_provider and not self.driver.is_mobile_platform:
672672
self.position_provider.push_state()
673673

674674
self._try_hide_caret()
@@ -683,7 +683,7 @@ def _get_screenshot(self):
683683
self._last_screenshot = self._viewport_screenshot(scale_provider)
684684

685685
with self._driver.switch_to.frames_and_back(self._original_frame_chain):
686-
if self.position_provider and not self.driver.is_mobile_device():
686+
if self.position_provider and not self.driver.is_mobile_platform:
687687
self.position_provider.pop_state()
688688

689689
return self._last_screenshot
@@ -790,7 +790,7 @@ def _ensure_element_visible(self, element):
790790
if self._target_element is None:
791791
# No element? we must be checking the window.
792792
return None
793-
if self.driver.is_mobile_device():
793+
if self.driver.is_mobile_platform:
794794
logger.debug("NATIVE context identified, skipping 'ensure element visible'")
795795
return None
796796

eyes_selenium/applitools/selenium/webdriver.py

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -96,27 +96,27 @@ def __init__(self, driver, switch_to):
9696
def frame_and_back(self, frame_reference):
9797
# type: (FrameReference) -> Generator
9898
cur_frame = None
99-
if not self._driver.is_mobile_device():
99+
if not self._driver.is_mobile_app:
100100
self.frame(frame_reference)
101101
cur_frame = self._driver.frame_chain.peek
102102

103103
yield cur_frame
104104

105-
if not self._driver.is_mobile_device():
105+
if not self._driver.is_mobile_app:
106106
self.parent_frame()
107107

108108
@contextlib.contextmanager
109109
def frames_and_back(self, frame_chain):
110110
# type: (FrameChain) -> Generator
111111
cur_frame = None
112112
origin_fc = self._driver.frame_chain.clone()
113-
if not self._driver.is_mobile_device():
113+
if not self._driver.is_mobile_app:
114114
self.frames(frame_chain)
115115
cur_frame = self._driver.frame_chain.peek
116116

117117
yield cur_frame
118118

119-
if not self._driver.is_mobile_device():
119+
if not self._driver.is_mobile_app:
120120
self.frames(origin_fc)
121121

122122
def frame(self, frame_reference):
@@ -324,14 +324,27 @@ def platform_version(self):
324324
return self._driver.desired_capabilities.get("platformVersion", None)
325325

326326
def is_mobile_device(self):
327+
logger.deprecation("Use `is_mobile_platform` property instead")
328+
return self.is_mobile_platform
329+
330+
@property
331+
def is_mobile_platform(self):
327332
# type: () -> bool
328333
"""
329334
Returns whether the platform running is a mobile device or not.
330335
331336
:return: True if the platform running the test is a mobile platform.
332337
False otherwise.
333338
"""
334-
return eyes_selenium_utils.is_mobile_device(self._driver)
339+
return eyes_selenium_utils.is_mobile_platform(self._driver)
340+
341+
@property
342+
def is_mobile_web(self):
343+
return eyes_selenium_utils.is_mobile_web(self._driver)
344+
345+
@property
346+
def is_mobile_app(self):
347+
return eyes_selenium_utils.is_mobile_app(self._driver)
335348

336349
def get(self, url):
337350
# type: (Text) -> Optional[Any]

tests/functional/eyes_selenium/test_appium.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ def test_selenium_and_appium_work(eyes_open):
7979

8080

8181
@pytest.mark.platform("iOS")
82-
@pytest.mark.test_page_url("http://applitools.github.io/demo/TestPages/FramesTestPage/")
82+
@pytest.mark.test_page_url("https://www.goodrx.com/")
8383
@pytest.mark.parametrize(
8484
"eyes",
8585
[

tests/unit/eyes_selenium/test_eyes_selenium_utils.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@
2121
)
2222
def test_different_mobile_platform_names(driver_mock, platform_name):
2323
driver_mock.desired_capabilities["platformName"] = platform_name
24-
assert eyes_selenium_utils.is_mobile_device(driver_mock)
24+
assert eyes_selenium_utils.is_mobile_web(driver_mock)
2525

2626

2727
@pytest.mark.parametrize("platform_name", ["Windows", "Winmo", "Linux", "macOs"])
2828
def test_different_not_mobile_platform_names(driver_mock, platform_name):
2929
driver_mock.desired_capabilities["platformName"] = platform_name
30-
assert not eyes_selenium_utils.is_mobile_device(driver_mock)
30+
assert not eyes_selenium_utils.is_mobile_web(driver_mock)
3131

3232

3333
def test_appium_webdriver(driver_mock):
3434
driver_mock._driver = mock.Mock(AppiumWebDriver)
35-
assert eyes_selenium_utils.is_mobile_device(driver_mock)
35+
assert eyes_selenium_utils.is_mobile_web(driver_mock)

0 commit comments

Comments
 (0)