def _wait_for_animation_starts(self, zone, timeout=DEFAULT_TIMEOUT, threshold=DEFAULT_THRESHOLD, step=0.05): timeout = float(timeout) threshold = float(threshold) step = float(step) new_screen = self._screenshot(zone) start_time = datetime.datetime.now() while True: utils.sleep(step) old_screen = new_screen new_screen = self._get_screen(False, zone) result = self._find_image_result(new_screen, old_screen, threshold) if not result.found: return True if (datetime.datetime.now() - start_time).seconds > timeout: break self.error_handler.report_warning( "Timeout exceeded while waiting for animation starts") return False
def _wait_for_image_to_hide(self, image, threshold=0.95, timeout=15, zone=None): timeout = float(timeout) start_time = datetime.datetime.now() img = self.load_image(image) while True: screen_img = self._screenshot(zone) result = self._find_image_result(img, screen_img, threshold) if not result.found: return True utils.sleep(0) if (datetime.datetime.now() - start_time).seconds > int(timeout): break image_info = ("image", result.image) screen_info = ("screen", result.screen) msg = "Waiting for image hide was unsucessfull for threshold {} and timeout {}".format( threshold, int(timeout)) self.error_handler.report_warning(msg, image_info, screen_info) return False
def wait_for_one_of(self, images, timeout=15, zone=None): # wait_for_one_of_images(images, timeout, step, zone) -> bool # images - list of (image, threshold, bool) # image - PIL image # threshold - threshold for image # bool - True for wait for show, False for wait for hide assert len(images) > 0, "You are trying to wait for empty list of images. Really?" timeout = float(timeout) start_time = datetime.datetime.now() while True: screen_img = self._screenshot(zone) for image_info in images: # todo: optimize result = self._find_image_result(image_info[0], screen_img, float(image_info[1])) if result.found == utils.to_bool(image_info[2]): return result utils.sleep(0) if (datetime.datetime.now() - start_time).seconds > timeout: break images_info = [] for index, image in enumerate(images): images_info.append(("image_{}_threshold_{}".format(index, image[1]), image[0])) images_info.append(("screen", screen_img)) self.error_handler.report_warning("Waiting for one of the images was unsuccessful", *images_info) return result
def find_on_screen(states, screen=None): #creates the Class object - image_processor image_processor = ImageProcessor() #checks if screen is provided, else gets the active window screenshot screen = screen if screen is not None else image_processor._get_screenshot( ) #collects images images_to_find = states.values() #searches for image in state on screen coords = image_processor.find_one_of(images_to_find, screen=screen) #if found - calculates the image position (coordinates) if coords is not None: return coords.get_pos() #try again if not found in first attempt ErrorHandler().report_warning("First try was unsuccessful") utils.sleep(0.020) coords = image_processor.find_one_of(images_to_find) if coords is not None: return coords.get_pos() #no one state is found #prepare the error message content images = [] for state_name, state_info in states.items(): images.append((state_name, state_info[0])) msg = "Button not found on screen in all possible states" images.append(("screen", screen)) ErrorHandler().report_error(msg, *images) raise RuntimeError(msg)
def wait_for_animation_starts(self, zone=None, timeout=15, threshold=0.99, step=0.5): #convert passed args to float values timeout = float(timeout) threshold = float(threshold) step = float(step) # gets the first screenshot from given zone (if zone is none, takes the whole active window) new_screen = ImageProcessor()._get_screen(False, zone) # saves the time starting point (when the first screenshot was taken) start_time = datetime.datetime.now() #In a loop compares the screenshot with previously taken from screen. #If images are NOT identical returns True, else continue until timeout occurs - throws error and returns False. while True: utils.sleep(step) old_screen = new_screen new_screen = ImageProcessor()._get_screen(False, zone) result = ImageProcessor().find_image_result( new_screen, old_screen, threshold) if not result.found: return True if (datetime.datetime.now() - start_time).seconds > timeout: break ErrorHandler().report_warning( "Timeout exceeded while waiting for animation starts") return False
def wait_for_image_to_hide(self, image, threshold=0.99, timeout=15, zone=None): timeout = float(timeout) start_time = datetime.datetime.now() # prepare image to analyze (PIL.Image format) img = self.load_image(image) # tries to locate image absence for given timeout while True: screen_img = self._get_screen(False, zone) result = self.find_image_result(img, screen_img, threshold) if not result.found: return True utils.sleep(0) if (datetime.datetime.now() - start_time).seconds > timeout: break image_info = ("image", result.image) screen_info = ("screen", result.screen) msg = "Waiting for image hide was unsuccessful for threshold {}".format( threshold) self.error_handler.report_warning(msg, image_info, screen_info) return False
def image_should_be_on_screen(self, image, threshold=0.99, cache=False, zone=None, screen=None): # Keyword tries to find image twice. # If the second try fails - fails. result = self.find_image(image, threshold, cache, zone, screen) if result.found: return True ErrorHandler().report_warning( "First try to locate image on screen was unsuccessful") #try again utils.sleep(0.020) result = self.find_image(image, threshold, cache, zone) if result.found: return True image_info = ("image", result.image) screen_info = ("screen", result.screen) msg = "Image was not found at screen with threshold {}".format( threshold) self.error_handler.report_error(msg, image_info, screen_info) raise RuntimeError(msg)
def _is_animating(self, zone, threshold, step): threshold = float(threshold) step = float(step) old_screen = self._get_screen(False, zone) utils.sleep(step) new_screen = self._get_screen(False, zone) return not self._find_image_result(new_screen, old_screen, threshold).found
def _is_zone_animating(self, zone, threshold=DEFAULT_THRESHOLD, step=0.5): threshold = float(threshold) step = float(step) old_screen = self._screenshot(zone) utils.sleep(step) new_screen = self._screenshot(zone) return not self._find_image_result(new_screen, old_screen, threshold).found
def is_animating(self, zone=None, threshold=0.99, step=0.5): # convert passed args to float values threshold = float(threshold) step = float(step) #gets the first screenshot than waits for 'step' time and gets the second screenshot old_screen = ImageProcessor()._get_screen(False, zone) utils.sleep(step) new_screen = ImageProcessor()._get_screen(False, zone) #compares the first and the second screenshots, returns result. If screenshots are identical - True. return not ImageProcessor().find_image_result(new_screen, old_screen, threshold).found
def window_should_be_on_screen(self): """Check window elements - check section, buttons, maybe smth more in future""" screen = ImageProcessor().get_screenshot() self._init_static_elements(screen) if "exist" in self.config: if not self._is_window_on_screen(screen)[0]: ErrorHandler().report_warning('First try was unsuccessful') utils.sleep(0.050) if not self._is_window_on_screen()[0]: ErrorHandler().report_error("Window {} is not on screen:".format(self.name), ("screen", screen)) raise RuntimeError("Window {} is not on screen (checked by exist section). Image {} not found".format(self.name, self._is_window_on_screen()[1])) else: raise errors.ConfigError("Is Window On Screen can't work if exists section is not defined; in window " + self.name)
def _wait_for_window_state(self, state, timeout): #state argument is boolean value. #loops for passed timeout trying to locate window on screen timeout = float(timeout) start_time = datetime.datetime.now() state_name = "shows" if state else "hides" while True: if self._is_window_on_screen()[0] == state: ErrorHandler().report_info("Successfully waited for {} {}".format(self.name, state_name)) return True utils.sleep(0) if (datetime.datetime.now() - start_time).seconds > timeout: ErrorHandler().report_warning("Timeout exceeded while trying to wait {} {}".format(self.name, state_name)) break return False
def _image_should_not_be_on_screen(self, image, threshold=0.99, cache=False, zone=None, screen=None): result = self._find_image(image, threshold, cache, zone, screen) if not result.found: return True self.error_handler.report_warning("First try was unsuccessful") # try again utils.sleep(0.020) result = self._find_image(image, threshold, cache, zone, screen) if not result.found: return True image_info = ("image", result.image) screen_info = ("screen", result.screen) msg = "Image was found on screen with threshold {}".format(threshold) self.error_handler.report_error(msg, image_info, screen_info) raise RuntimeError(msg)
def wait_for_image_to_stop(self, image, threshold=0.99, timeout=15, move_threshold=0.99, step=0.1): timeout = float(timeout) threshold = float(threshold) move_threshold = float(move_threshold) step = float(step) assert 0 < threshold <= 1, "Threshold must be in (0, 1]" assert 0 < move_threshold <= 1, "Move threshold must be in (0, 1)" # prepare image to analyze (PIL.Image format) img = self.load_image(image) # calculate start time for timeout start_time = datetime.datetime.now() #get screenshot and locate image on it new_screen = self._get_screenshot() new_pos = self.find_image_result(img, new_screen, threshold) #compares last and current OpenCV template search results. while True: old_screen = new_screen old_pos = new_pos utils.sleep(step) new_screen = self._get_screenshot() new_pos = self.find_image_result(img, new_screen, threshold) if old_pos.found and new_pos.found: #template is on screen, not blinking and whatever else #calculate the distance from the origin to the coordinates given (Euclidian norm) ds = math.hypot(new_pos.x - old_pos.x, new_pos.y - old_pos.y) diag = 1280 #hypot for 1024x768 if 1 - ds / diag > threshold: return True if (datetime.datetime.now() - start_time).seconds > timeout: break image_info = ("image", new_pos.image) screen_info = ("screen", new_pos.screen) msg = "Waiting for image stop was unsuccessful for threshold {}".format( threshold) self.error_handler.report_warning(msg, image_info, screen_info) return False
def _wait_for_image_to_stop(self, image, threshold=0.95, timeout=15, move_threshold=0.99, step=0.1): timeout = float(timeout) threshold = float(threshold) move_threshold = float(move_threshold) step = float(step) assert threshold > 0 and threshold <= 1, "Threshold must be in (0, 1]" assert move_threshold > 0 and move_threshold <= 1, "Move threshold must be in (0, 1]" img = self.load_image(image) start_time = datetime.datetime.now() new_screen = self._screenshot() new_pos = self._find_image_result(img, new_screen, threshold) while True: old_scren = new_screen old_pos = new_pos utils.sleep(step) new_screen = self._screenshot() new_pos = self._find_image_result(img, new_screen, threshold) if old_pos.found and new_pos.found: # template is on screen, not blinking and whatever else ds = math.hypot(new_pos.x - old_pos.x, new_pos.y - old_pos.y) diag = 1280 # hypot for 1024x768 if 1 - ds / diag > threshold: return True if (datetime.datetime.now() - start_time).seconds > int(timeout): break image_info = ("image", new_pos.image) screen_info = ("screen", new_pos.screen) msg = "Waiting for image stop was unsucessfull for threshold {} and timeout {}".format( threshold, int(timeout)) self.error_handler.report_warning(msg, image_info, screen_info) return False
def wait_for_one_of(self, images, timeout=15, zone=None): """wait_for_one_of_images(images, timeout, step, zone) -> bool images - list of (image, threshold, bool) image - PIL image threshold - threshold for image bool - True for wait for show, False for wait for hide """ assert len( images ) > 0, "You are trying to wait for empty list of images. Really?" timeout = float(timeout) start_time = datetime.datetime.now() #loops through images in list and locates image on screen. Returns search results. #if not timeout repeats taking new screenshots and searching images on it. #ends loop on timeout while True: screen_img = self._get_screen(False, zone) for image_info in images: #todo: optimize result = self.find_image_result(image_info[0], screen_img, float(image_info[1])) if result.found == utils.to_bool(image_info[2]): return result utils.sleep(0) if (datetime.datetime.now() - start_time).seconds > timeout: break images_info = [] for index, image in enumerate(images): images_info.append( ("image_{}_threshold_{}".format(index, image[1]), image[0])) images_info.append(("screen", screen_img)) self.error_handler.report_warning( "Waiting for one of the images was unsuccessful", *images_info) return result