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

Commit 02a0552

Browse files
authored
Fix repeated steps (#13)
* Run match_window only once * Remove option to set retry_timeout * Set retry_timeout to 0 * Fix ignore_mismatch param
1 parent 70a2e9d commit 02a0552

File tree

4 files changed

+79
-78
lines changed

4 files changed

+79
-78
lines changed

eyes_core/applitools/core/match_window_task.py

Lines changed: 59 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
from __future__ import absolute_import
22

3-
import functools
43
import time
54
import typing as tp
65
from struct import pack
@@ -56,7 +55,7 @@ def __init__(self, eyes, server_connector, running_session, default_retry_timeou
5655
self._default_retry_timeout = (
5756
default_retry_timeout / 1000.0
5857
) # type: Num # since we want the time in seconds.
59-
self._screenshot = None # type: tp.Optional[EyesScreenshot]
58+
self._last_screenshot = None # type: tp.Optional[EyesScreenshot]
6059

6160
@staticmethod
6261
def _create_match_data_bytes(
@@ -143,14 +142,16 @@ def _prepare_match_data_for_window(
143142
# TODO: Refactor this
144143
if hasattr(self._eyes, "_hide_scrollbars_if_needed"):
145144
with self._eyes._hide_scrollbars_if_needed(): # type: ignore
146-
self._screenshot = self._eyes.get_screenshot(
145+
self._last_screenshot = self._eyes.get_screenshot(
147146
hide_scrollbars_called=True
148147
)
149148
else:
150-
self._screenshot = self._eyes.get_screenshot()
149+
self._last_screenshot = self._eyes.get_screenshot()
151150

152-
dynamic_regions = MatchWindowTask._get_dynamic_regions(target, self._screenshot)
153-
app_output = {"_title": title, "screenshot64": None} # type: AppOutput
151+
dynamic_regions = MatchWindowTask._get_dynamic_regions(
152+
target, self._last_screenshot
153+
)
154+
app_output = {"title": title, "screenshot64": None} # type: AppOutput
154155

155156
if self._eyes.send_dom:
156157
dom_json = self._eyes._try_capture_dom()
@@ -167,50 +168,86 @@ def _prepare_match_data_for_window(
167168
user_inputs,
168169
tag,
169170
ignore_mismatch,
170-
self._screenshot,
171+
self._last_screenshot,
171172
default_match_settings,
172173
target,
173174
dynamic_regions["ignore"],
174175
dynamic_regions["floating"],
175176
)
176177

177-
def _run_with_intervals(self, prepare_action, retry_timeout):
178-
# type: (tp.Callable, Num) -> MatchResult
178+
def _run_with_intervals(self, prepare_match_data_options, retry_timeout):
179+
# type: (tp.Dict, Num) -> MatchResult
179180
"""
180181
Includes retries in case the screenshot does not match.
181182
"""
182183
logger.debug("Matching with intervals...")
183184
# We intentionally take the first screenshot before starting the timer,
184185
# to allow the page just a tad more time to stabilize.
185-
data = prepare_action()
186+
prepare_match_data_options = prepare_match_data_options.copy()
187+
prepare_match_data_options["ignore_mismatch"] = True
188+
data = self._prepare_match_data_for_window(**prepare_match_data_options)
189+
186190
# Start the timer.
187191
start = time.time()
188192
logger.debug("First match attempt...")
189193
as_expected = self._server_connector.match_window(self._running_session, data)
190194
if as_expected:
191-
return {"as_expected": True, "screenshot": self._screenshot}
195+
return {"as_expected": True, "screenshot": self._last_screenshot}
192196
retry = time.time() - start
193197
logger.debug("Failed. Elapsed time: {0:.1f} seconds".format(retry))
194198

195199
while retry < retry_timeout:
196200
logger.debug("Matching...")
197201
time.sleep(self.MATCH_INTERVAL)
198-
data = prepare_action(ignore_mismatch=True)
202+
203+
data = self._prepare_match_data_for_window(**prepare_match_data_options)
199204
as_expected = self._server_connector.match_window(
200205
self._running_session, data
201206
)
202207
if as_expected:
203-
return {"as_expected": True, "screenshot": self._screenshot}
208+
return {"as_expected": True, "screenshot": self._last_screenshot}
204209
retry = time.time() - start
205210
logger.debug("Elapsed time: {0:.1f} seconds".format(retry))
211+
206212
# One last try
207213
logger.debug("One last matching attempt...")
208-
data = prepare_action()
214+
prepare_match_data_options["ignore_mismatch"] = False
215+
data = self._prepare_match_data_for_window(**prepare_match_data_options)
209216
as_expected = self._server_connector.match_window(self._running_session, data)
210-
return {"as_expected": as_expected, "screenshot": self._screenshot}
217+
return {"as_expected": as_expected, "screenshot": self._last_screenshot}
218+
219+
def match_window(
220+
self,
221+
retry_timeout, # type: Num
222+
tag, # type: str
223+
user_inputs, # UserInputs
224+
default_match_settings, # type: ImageMatchSettings
225+
target,
226+
ignore_mismatch,
227+
run_once_after_wait=False,
228+
):
229+
# type: (...) -> MatchResult
230+
"""
231+
Performs a match for the window.
232+
233+
:param retry_timeout: Amount of time until it retries.
234+
:param tag: The name of the tag (optional).
235+
:param user_inputs: The user input.
236+
:param default_match_settings: The default match settings for the session.
237+
:param target: The target of the check_window call.
238+
:param ignore_mismatch: True if the server should ignore a negative result
239+
for the visual validation.
240+
:param run_once_after_wait: Whether or not to run again after waiting.
241+
:return: The result of the run.
242+
"""
243+
prepare_match_data_options = dict(
244+
tag=tag,
245+
user_inputs=user_inputs,
246+
default_match_settings=default_match_settings,
247+
target=target,
248+
ignore_mismatch=ignore_mismatch,
249+
)
211250

212-
def _run(self, prepare_action, run_once_after_wait=False, retry_timeout=-1):
213-
# type: (tp.Callable, bool, Num) -> MatchResult
214251
if 0 < retry_timeout < MatchWindowTask.MINIMUM_MATCH_TIMEOUT:
215252
raise ValueError(
216253
"Match timeout must be at least 60ms, got {} instead.".format(
@@ -221,57 +258,25 @@ def _run(self, prepare_action, run_once_after_wait=False, retry_timeout=-1):
221258
retry_timeout = self._default_retry_timeout
222259
else:
223260
retry_timeout /= 1000.0
261+
224262
logger.debug("Match timeout set to: {0} seconds".format(retry_timeout))
225263
start = time.time()
226264
if run_once_after_wait or retry_timeout == 0:
227265
logger.debug("Matching once...")
228266
# If the load time is 0, the sleep would immediately return anyway.
229267
time.sleep(retry_timeout)
230-
data = prepare_action()
268+
data = self._prepare_match_data_for_window(**prepare_match_data_options)
231269
as_expected = self._server_connector.match_window(
232270
self._running_session, data
233271
)
234272
result = {
235273
"as_expected": as_expected,
236-
"screenshot": self._screenshot,
274+
"screenshot": self._last_screenshot,
237275
} # type: MatchResult
238276
else:
239-
result = self._run_with_intervals(prepare_action, retry_timeout)
277+
result = self._run_with_intervals(prepare_match_data_options, retry_timeout)
278+
240279
logger.debug("Match result: {0}".format(result["as_expected"]))
241280
elapsed_time = time.time() - start
242281
logger.debug("_run(): Completed in {0:.1f} seconds".format(elapsed_time))
243282
return result
244-
245-
def match_window(
246-
self,
247-
retry_timeout, # type: Num
248-
tag, # type: str
249-
user_inputs, # UserInputs
250-
default_match_settings, # type: ImageMatchSettings
251-
target,
252-
ignore_mismatch,
253-
run_once_after_wait=False,
254-
):
255-
# type: (...) -> MatchResult
256-
"""
257-
Performs a match for the window.
258-
259-
:param retry_timeout: Amount of time until it retries.
260-
:param tag: The name of the tag (optional).
261-
:param user_inputs: The user input.
262-
:param default_match_settings: The default match settings for the session.
263-
:param target: The target of the check_window call.
264-
:param ignore_mismatch: True if the server should ignore a negative result
265-
for the visual validation.
266-
:param run_once_after_wait: Whether or not to run again after waiting.
267-
:return: The result of the run.
268-
"""
269-
prepare_action = functools.partial(
270-
self._prepare_match_data_for_window,
271-
tag,
272-
user_inputs,
273-
default_match_settings,
274-
target,
275-
ignore_mismatch,
276-
)
277-
return self._run(prepare_action, run_once_after_wait, retry_timeout)

eyes_core/applitools/core/server_connector.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -214,7 +214,7 @@ def stop_session(self, running_session, is_aborted, save):
214214
)
215215

216216
def match_window(self, running_session, data):
217-
# type: (RunningSession, tp.Text) -> bool
217+
# type: (RunningSession, bytes) -> bool
218218
"""
219219
Matches the current window to the immediate expected window in the Eyes server.
220220
Notice that a window might be matched later at the end of the test, even if it

eyes_images/applitools/images/eyes.py

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -72,34 +72,27 @@ def check(self, name, target):
7272
return False
7373
return self._check_image(name, False, target)
7474

75-
def check_image(self, image, tag=None, ignore_mismatch=False, retry_timeout=-1):
76-
# type: (Union[Image.Image, Text], Optional[Text], bool, int) -> Optional[bool]
75+
def check_image(self, image, tag=None, ignore_mismatch=False):
76+
# type: (Union[Image.Image, Text], Optional[Text], bool) -> Optional[bool]
7777
if self.is_disabled:
7878
return None
7979
logger.info(
80-
"check_image(Image {}, tag {}, ignore_mismatch {}, retry_timeout {}".format(
81-
image, tag, ignore_mismatch, retry_timeout
80+
"check_image(Image {}, tag {}, ignore_mismatch {}".format(
81+
image, tag, ignore_mismatch
8282
)
8383
)
84-
return self._check_image(
85-
tag, ignore_mismatch, Target().image(image).timeout(retry_timeout)
86-
)
84+
return self._check_image(tag, ignore_mismatch, Target().image(image))
8785

88-
def check_region(
89-
self, image, region, tag=None, ignore_mismatch=False, retry_timeout=-1
90-
):
91-
# type: (Image.Image, Region, Optional[Text], bool, int) -> Optional[bool]
86+
def check_region(self, image, region, tag=None, ignore_mismatch=False):
87+
# type: (Image.Image, Region, Optional[Text], bool) -> Optional[bool]
9288
if self.is_disabled:
9389
return None
9490
logger.info(
95-
"check_region(Image {}, region {}, tag {}, "
96-
"ignore_mismatch {}, retry_timeout {}".format(
97-
image, region, tag, ignore_mismatch, retry_timeout
91+
"check_region(Image {}, region {}, tag {}, ignore_mismatch {}".format(
92+
image, region, tag, ignore_mismatch
9893
)
9994
)
100-
return self._check_image(
101-
tag, ignore_mismatch, Target().region(image, region).timeout(retry_timeout)
102-
)
95+
return self._check_image(tag, ignore_mismatch, Target().region(image, region))
10396

10497
def _check_image(self, name, ignore_mismatch, target):
10598
# type: (Text, bool, Target) -> bool
@@ -110,12 +103,13 @@ def _check_image(self, name, ignore_mismatch, target):
110103
self.abort_if_not_closed()
111104
raise EyesError("you must call open() before checking")
112105

113-
image = target._image # type: Image.Image
106+
image = target.values.image # type: Image.Image
107+
timeout = 0 # run match_window once
114108
self._screenshot = EyesImagesScreenshot(image)
115109
if not self._viewport_size:
116110
self.set_viewport_size(dict(width=image.width, height=image.height))
117111

118-
match_result = self._check_window_base(name, -1, target, ignore_mismatch)
112+
match_result = self._check_window_base(name, timeout, target, ignore_mismatch)
119113
self._screenshot = None
120114
self._raw_title = None
121115
return match_result["as_expected"]

eyes_images/applitools/images/target.py

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@
22

33
import typing as tp
44

5-
from PIL import Image
6-
75
from applitools.core import RegionProvider
8-
from applitools.core.utils import image_utils
96
from applitools.core.errors import EyesError
107
from applitools.core.geometry import Region
8+
from applitools.core.utils import image_utils
9+
from PIL import Image
1110

1211
if tp.TYPE_CHECKING:
1312
from applitools.images.capture import EyesImagesScreenshot
@@ -88,6 +87,10 @@ def ignore_regions(self):
8887
def floating_regions(self):
8988
return self.check_settings._floating_regions
9089

90+
@property
91+
def image(self):
92+
return self.check_settings._image
93+
9194

9295
# Main class for the module
9396
class Target(object):
@@ -99,7 +102,6 @@ class Target(object):
99102
__floating_regions = None # type: tp.Optional[tp.List]
100103
_image = None # type: tp.Optional[EyesImagesScreenshot]
101104
_target_region = None # type: tp.Optional[Region]
102-
_timeout = -1
103105

104106
_ignore_caret = None
105107

0 commit comments

Comments
 (0)