|
6 | 6 | import requests
|
7 | 7 |
|
8 | 8 | from selenium.webdriver import __version__ as SELENIUM_VERSION
|
| 9 | +from selenium.common.exceptions import TimeoutException |
| 10 | +from selenium.webdriver.support.ui import WebDriverWait |
9 | 11 | from percy.version import __version__ as SDK_VERSION
|
10 | 12 | from percy.driver_metadata import DriverMetaData
|
11 | 13 |
|
|
16 | 18 | # Maybe get the CLI API address from the environment
|
17 | 19 | PERCY_CLI_API = os.environ.get('PERCY_CLI_API') or 'http://localhost:5338'
|
18 | 20 | PERCY_DEBUG = os.environ.get('PERCY_LOGLEVEL') == 'debug'
|
| 21 | +RESONSIVE_CAPTURE_SLEEP_TIME = os.environ.get('RESONSIVE_CAPTURE_SLEEP_TIME') |
19 | 22 |
|
20 | 23 | # for logging
|
21 | 24 | LABEL = '[\u001b[35m' + ('percy:python' if PERCY_DEBUG else 'percy') + '\u001b[39m]'
|
@@ -89,28 +92,48 @@ def get_widths_for_multi_dom(width, widths):
|
89 | 92 | allWidths.extend(eligible_widths.get('config', []))
|
90 | 93 | return list(set(allWidths))
|
91 | 94 |
|
92 |
| -def change_window_dimension(driver, width, height): |
| 95 | +def change_window_dimension_and_wait(driver, width, height, resizeCount): |
93 | 96 | if CDP_SUPPORT_SELENIUM and driver.capabilities['browserName'] == 'chrome':
|
94 | 97 | driver.execute_cdp_cmd('Emulation.setDeviceMetricsOverride', { 'height': height,
|
95 | 98 | 'width': width, 'deviceScaleFactor': 1, 'mobile': False })
|
96 | 99 | else:
|
97 | 100 | driver.set_window_size(width, height)
|
98 | 101 |
|
| 102 | + try: |
| 103 | + WebDriverWait(driver, 2).until( |
| 104 | + lambda driver: driver.execute_script("return window.resizeCount") == resizeCount |
| 105 | + ) |
| 106 | + except TimeoutException: |
| 107 | + if PERCY_DEBUG: log(f"Timed out waiting for window resize event for width {width}") |
| 108 | + |
| 109 | + |
99 | 110 | def capture_responsive_dom(driver, cookies, **kwargs):
|
100 | 111 | # cache doesn't work when parameter is a list so passing tuple
|
101 | 112 | widths = get_widths_for_multi_dom(kwargs.get('width'), tuple(kwargs.get('widths') or []))
|
102 | 113 | dom_snapshots = []
|
103 | 114 | window_size = driver.get_window_size()
|
104 | 115 | current_width, current_height = window_size['width'], window_size['height']
|
| 116 | + resize_count = 0 |
| 117 | + driver.execute_script(""" |
| 118 | + // if window resizeCount present means event listener was already present |
| 119 | + if (!window.resizeCount) { |
| 120 | + window.addEventListener('resize', () => { |
| 121 | + window.resizeCount++; |
| 122 | + }) |
| 123 | + } |
| 124 | + // always reset count 0 |
| 125 | + window.resizeCount = 0 |
| 126 | + """) |
105 | 127 |
|
106 | 128 | for width in widths:
|
107 |
| - change_window_dimension(driver, width, current_height) |
108 |
| - sleep(1) |
| 129 | + resize_count += 1 |
| 130 | + change_window_dimension_and_wait(driver, width, current_height, resize_count) |
| 131 | + if RESONSIVE_CAPTURE_SLEEP_TIME: sleep(int(RESONSIVE_CAPTURE_SLEEP_TIME)) |
109 | 132 | dom_snapshot = get_serialized_dom(driver, cookies, **kwargs)
|
110 | 133 | dom_snapshot['width'] = width
|
111 | 134 | dom_snapshots.append(dom_snapshot)
|
112 | 135 |
|
113 |
| - change_window_dimension(driver, current_width, current_height) |
| 136 | + change_window_dimension_and_wait(driver, current_width, current_height, resize_count + 1) |
114 | 137 | return dom_snapshots
|
115 | 138 |
|
116 | 139 | # Take a DOM snapshot and post it to the snapshot endpoint
|
|
0 commit comments