def compare_image(self, path, imagename=None, ignore_mismatch=False, includeEyesLog=False, httpDebugLog=False): """ Select an image and send it to Eyes for comparison. A name can be used in place of the image's file name. Arguments: | Path | Path of the image to send to eyes for visual comparison. | | imagename (default=None) | Can manually set the name desired for the image passed in. If no name is passed in it will default file name of the image. | | Include Eyes Log (default=False) | The Eyes logs will not be included by default. To activate, pass 'True' in the variable. | | HTTP Debug Log (default=False) | The HTTP Debug logs will not be included by default. To activate, pass 'True' in the variable. | Example: | *Keywords* | *Parameters* | | Open Browser | http://www.navinet.net/ | gc | | | | | | Open Eyes Session | http://www.navinet.net/ | RobotAppEyes_Test | NaviNet_RobotAppEyes_Test | YourApplitoolsKey | 1024 | 768 | | Compare Image | selenium-screenshot-1.png | Image Name Example | | | | | | Close Eyes Session | | | | | | | """ if imagename is None: tag = os.path.basename(path) else: tag = imagename eyes._prepare_to_check() if includeEyesLog is True: logger.set_logger(StdoutLogger()) logger.open_() if httpDebugLog is True: httplib.HTTPConnection.debuglevel = 1 with open(path, 'rb') as image_file: screenshot64 = image_file.read().encode('base64') screenshot = _image_utils.png_image_from_bytes( base64.b64decode(screenshot64)) screenshotBytes = EyesScreenshot.create_from_image( screenshot, eyes._driver) title = eyes.get_title() app_output = {'title': title, 'screenshot64': None} user_inputs = [] prepare_match_data = eyes._match_window_task._create_match_data_bytes( app_output, user_inputs, tag, ignore_mismatch, screenshotBytes) eyes._match_window_task._agent_connector.match_window( eyes._match_window_task._running_session, prepare_match_data)
def get_screenshot_as_base64(self): """ Gets the screenshot of the current window as a base64 encoded string which is useful in embedded images in HTML. """ screenshot64 = self.driver.get_screenshot_as_base64() display_rotation = self.get_display_rotation() if display_rotation != 0: logger.info('Rotation required.') num_quadrants = int(-(display_rotation / 90)) logger.debug('decoding base64...') screenshot_bytes = base64.b64decode(screenshot64) logger.debug('Done! Creating image object...') screenshot = _image_utils.png_image_from_bytes(screenshot_bytes) logger.debug('Done! Rotating...') screenshot.quadrant_rotate(num_quadrants) screenshot64 = screenshot.get_base64() return screenshot64
def __init__(self, driver, screenshot=None, screenshot64=None, is_viewport_screenshot=None, frame_location_in_screenshot=None): """ Initializes a Screenshot instance. Either screenshot or screenshot64 must NOT be None. Should not be used directly. Use create_from_image/create_from_base64 instead. Args: driver: EyesWebDriver instance which handles the session from which the screenshot was retrieved. (Optional) screenshot: (PngImage) image instance. If screenshot64 is None, this variable must NOT be none. (Optional) screenshot64: (str) The base64 representation of a png image. If screenshot is None, this variable must NOT be none. (Optional) frame_location_in_screenshot: (Point) The location of the frame relative to the top,left of the screenshot. (Optional) is_viewport_screenshot: (boolean) Whether the screenshot object represents a viewport screenshot or a full screenshot. """ self._screenshot64 = screenshot64 if screenshot: self._screenshot = screenshot elif screenshot64: self._screenshot = _image_utils.png_image_from_bytes( base64.b64decode(screenshot64)) else: raise EyesError("both screenshot and screenshot64 are None!") self._driver = driver self._viewport_size = driver.get_default_content_viewport_size() self._frame_chain = driver.get_frame_chain() if self._frame_chain: chain_len = len(self._frame_chain) self._frame_size = self._frame_chain[chain_len - 1].size else: try: self._frame_size = driver.get_entire_page_size() except WebDriverException: # For Appium, we can't get the "entire page size", so we use the viewport size. self._frame_size = self._viewport_size # For native Appium Apps we can't get the scroll position, so we use (0,0) try: self._scroll_position = driver.get_current_position() except WebDriverException: self._scroll_position = Point(0, 0) if is_viewport_screenshot is None: is_viewport_screenshot = self._screenshot.width <= self._viewport_size['width'] \ and self._screenshot.height <= self._viewport_size['height'] self._is_viewport_screenshot = is_viewport_screenshot if frame_location_in_screenshot is None: if self._frame_chain: frame_location_in_screenshot = EyesScreenshot \ .calc_frame_location_in_screenshot(self._frame_chain, is_viewport_screenshot) else: # The frame is the default content frame_location_in_screenshot = Point(0, 0) if self._is_viewport_screenshot: frame_location_in_screenshot.offset( -self._scroll_position.x, -self._scroll_position.y) self._frame_location_in_screenshot = frame_location_in_screenshot self._frame_screenshot_intersect = Region( frame_location_in_screenshot.x, frame_location_in_screenshot.y, self._frame_size['width'], self._frame_size['height']) self._frame_screenshot_intersect.intersect( Region(width=self._screenshot.width, height=self._screenshot.height))
def get_full_page_screenshot(self): logger.info('getting full page screenshot..') # Saving the current frame reference and moving to the outermost frame. original_frame = self.get_frame_chain() self.switch_to.default_content() self.reset_origin() entire_page_size = self.get_entire_page_size() # Starting with the screenshot at 0,0 part64 = self.get_screenshot_as_base64() screenshot = _image_utils.png_image_from_bytes( base64.b64decode(part64)) # IMPORTANT This is required! Since when calculating the screenshot parts for full size, # we use a screenshot size which is a bit smaller (see comment below). if (screenshot.width >= entire_page_size['width']) and \ (screenshot.height >= entire_page_size['height']): self.restore_origin() self.switch_to.frames(original_frame) return screenshot # We use a smaller size than the actual screenshot size in order to eliminate duplication # of bottom scroll bars, as well as footer-like elements with fixed position. screenshot_part_size = { 'width': screenshot.width, 'height': max(screenshot.height - self._MAX_SCROLL_BAR_SIZE, self._MIN_SCREENSHOT_PART_HEIGHT) } logger.debug("Total size: {0}, Screenshot part size: {1}".format( entire_page_size, screenshot_part_size)) entire_page = Region(0, 0, entire_page_size['width'], entire_page_size['height']) screenshot_parts = entire_page.get_sub_regions(screenshot_part_size) # Starting with the screenshot we already captured at (0,0). stitched_image = screenshot self.save_position() for part in screenshot_parts: # Since we already took the screenshot for 0,0 if part.left == 0 and part.top == 0: logger.debug('Skipping screenshot for 0,0 (already taken)') continue logger.debug("Taking screenshot for {0}".format(part)) # Scroll to the part's top/left and give it time to stabilize. self.scroll_to(Point(part.left, part.top)) time.sleep(0.1) # Since screen size might cause the scroll to reach only part of the way current_scroll_position = self.get_current_position() logger.debug("Scrolled To ({0},{1})".format( current_scroll_position.x, current_scroll_position.y)) part64 = self.get_screenshot_as_base64() part_image = _image_utils.png_image_from_bytes( base64.b64decode(part64)) stitched_image.paste(current_scroll_position.x, current_scroll_position.y, part_image.pixel_bytes) self.restore_position() self.restore_origin() self.switch_to.frames(original_frame) return stitched_image