def _full_page_screenshot(self, scale_provider): # type: (ScaleProvider) -> EyesWebDriverScreenshot logger.info("Full page screenshot requested") original_fc = self.driver.frame_chain.clone() if original_fc.size > 0: original_frame_position = original_fc.default_content_scroll_position else: original_frame_position = Point.ZERO() with self.driver.switch_to.frames_and_back(self._original_fc): scroll_root_element = eyes_selenium_utils.curr_frame_scroll_root_element( self.driver) origin_provider = ScrollPositionProvider(self.driver, scroll_root_element) origin_provider.set_position(Point.ZERO()) logger.debug("resetting origin_provider location") location = self.scroll_root_element.location size_and_borders = self.scroll_root_element.size_and_borders region = Region( location["x"] + size_and_borders.borders["left"], location["y"] + size_and_borders.borders["top"], size_and_borders.size["width"], size_and_borders.size["height"], ) algo = self._create_full_page_capture_algorithm(scale_provider) image = algo.get_stitched_region(region, Region.EMPTY(), self.position_provider) return EyesWebDriverScreenshot.create_full_page( self._driver, image, original_frame_position)
def _region_from_element(element, screenshot): # type: (AnyWebElement, EyesWebDriverScreenshot) -> Region location = element.location if screenshot: # Element's coordinates are context relative, so we need to convert them first. adjusted_location = screenshot.location_in_screenshot( Point.from_(location), CoordinatesType.CONTEXT_RELATIVE) else: adjusted_location = Point.from_(location) region = Region.from_(adjusted_location, element.size) return region
def __init__(self, image, location=None): super(EyesImagesScreenshot, self).__init__(image) if location is None: location = Point.ZERO() argument_guard.is_a(location, Point) self._location = location self._bounds = Region.from_(location, self.image)
def will_switch_to_frame(self, target_frame): # type: (EyesWebElement) -> None """ Will be called before switching into a frame. :param target_frame: The element about to be switched to. """ argument_guard.not_none(target_frame) pl = target_frame.location size_and_borders = target_frame.size_and_borders borders = size_and_borders.borders frame_inner_size = size_and_borders.size content_location = Point(pl["x"] + borders["left"], pl["y"] + borders["top"]) sp = ScrollPositionProvider( self._driver, self._driver.find_element_by_tag_name("html")) original_location = sp.get_current_position() sp.set_position(original_location) frame = Frame( target_frame, content_location, target_frame.size, frame_inner_size, parent_scroll_position=original_location, ) self._driver.frame_chain.push(frame)
def _full_page_screenshot(self, scale_provider): # type: (ScaleProvider) -> EyesWebDriverScreenshot logger.info("Full page screenshot requested") original_fc = self.driver.frame_chain.clone() if original_fc.size > 0: original_frame_position = original_fc.default_content_scroll_position else: original_frame_position = Point.zero() with self.driver.switch_to.frames_and_back(self._original_frame_chain): location = self.scroll_root_element.location size_and_borders = self.scroll_root_element.size_and_borders region = Region( location["x"] + size_and_borders.borders["left"], location["y"] + size_and_borders.borders["top"], size_and_borders.size["width"], size_and_borders.size["height"], ) algo = self._create_full_page_capture_algorithm(scale_provider) image = algo.get_stitched_region(region, None, self.position_provider) return EyesWebDriverScreenshot.create_full_page( self._driver, image, original_frame_position)
def _ensure_element_visible(self, element): position_provider = None if self._target_element and not self.driver.is_mobile_app: original_fc = self.driver.frame_chain.clone() eyes_element = EyesWebElement(element, self.driver) element_bounds = eyes_element.bounds current_frame_offset = original_fc.current_frame_offset element_bounds = element_bounds.offset(current_frame_offset) viewport_bounds = self._get_viewport_scroll_bounds() logger.info("viewport_bounds: {}; element_bounds: {}".format( viewport_bounds, element_bounds)) if not viewport_bounds.contains(element_bounds): self._ensure_frame_visible() element_location = Point.from_(element.location) if len(original_fc ) > 0 and element is not original_fc.peek.reference: fc = original_fc self.driver.switch_to.frames(original_fc) scroll_root_element = eyes_selenium_utils.curr_frame_scroll_root_element( self.driver, self._scroll_root_element) else: fc = self.driver.frame_chain.clone() scroll_root_element = self.scroll_root_element position_provider = self._element_position_provider_from( scroll_root_element) state = position_provider.get_state() position_provider.set_position(element_location) yield position_provider if self._target_element and position_provider and not self.driver.is_mobile_app: self.driver.switch_to.frames(fc) position_provider.restore_state(state)
def _ensure_element_visible(self, element): if self._target_element is None: # No element? we must be checking the window. return None if self.driver.is_mobile_platform: logger.debug( "NATIVE context identified, skipping 'ensure element visible'") return None original_fc = self.driver.frame_chain.clone() switch_to = self.driver.switch_to eyes_element = EyesWebElement(element, self.driver) element_bounds = eyes_element.bounds current_frame_offset = original_fc.current_frame_offset element_bounds.offset(current_frame_offset.x, current_frame_offset.y) viewport_bounds = self._get_viewport_scroll_bounds() logger.info("viewport_bounds: {}; element_bounds: {}".format( viewport_bounds, element_bounds)) if not element_bounds.contains(viewport_bounds): self._ensure_frame_visible() element_location = Point.from_(element.location) if len(original_fc ) > 0 and element is not original_fc.peek.reference: switch_to.frames(original_fc) scroll_root_element = self.driver.find_element_by_tag_name( "html") else: scroll_root_element = self.scroll_root_element position_provider = self._element_position_provider_from( scroll_root_element) position_provider.set_position(element_location)
def get_region(): rect = check_settings.values.target_region if rect is None: if self.driver.is_mobile_platform: bounds = self._target_element.rect else: bounds = self._target_element.bounding_client_rect region = Region( bounds["x"], bounds["y"], bounds["width"], bounds["height"], coordinates_type=CoordinatesType.CONTEXT_RELATIVE, ) else: s = self._target_element.size_and_borders.size b = self._target_element.size_and_borders.borders p = Point.from_(self._target_element.location) p = p.offset(b["left"], b["top"]) x = p.x + rect.left y = p.y + rect.top w = min(p.x + s["width"], rect.right) - x h = min(p.y + s["height"], rect.bottom) - y region = Region(x, y, w, h, CoordinatesType.CONTEXT_RELATIVE) return region
def _ensure_frame_visible(self): logger.debug("scroll_root_element_: {}".format(self._scroll_root_element)) current_fc = self.driver.frame_chain.clone() fc = self.driver.frame_chain.clone() self.driver.execute_script("window.scrollTo(0,0);") origin_driver = eyes_selenium_utils.get_underlying_driver(self.driver) while len(fc) > 0: logger.debug("fc count: {}".format(fc.size)) self.driver.switch_to.parent_frame_static(origin_driver.switch_to, fc) self.driver.execute_script("window.scrollTo(0,0);") child_frame = fc.pop() parent_frame = fc.peek scroll_root_element = None if fc.size == self._original_fc.size: logger.debug("PositionProvider: {}".format(self.position_provider)) self._position_memento = self.position_provider.get_state() scroll_root_element = self._scroll_root_element else: if parent_frame: scroll_root_element = parent_frame.scroll_root_element if not scroll_root_element: scroll_root_element = self.driver.find_element_by_tag_name("html") logger.debug("scroll_root_element {}".format(scroll_root_element)) position_provider = self._element_position_provider_from( scroll_root_element ) position_provider.set_position(child_frame.location) reg = Region.from_(Point.ZERO(), child_frame.inner_size) self._effective_viewport.intersect(reg) self.driver.switch_to.frames(current_fc) return current_fc
def _do_switch_to_frame(self, target_frame): # type: (EyesWebElement) -> None """ Will be called when switching into a frame. :param target_frame: The element to be switched to. """ argument_guard.not_none(target_frame) size_and_borders = target_frame.size_and_borders borders = size_and_borders.borders frame_inner_size = size_and_borders.size bounds = target_frame.bounding_client_rect content_location = Point( bounds["x"] + borders["left"], bounds["y"] + borders["top"] ) outer_size = RectangleSize.from_(target_frame.size) inner_size = RectangleSize.from_(frame_inner_size) original_location = target_frame.scroll_location self._switch_to.frame(target_frame.element) scroll_root_element = self._driver.find_element_by_xpath("/*") frame = Frame( reference=target_frame, location=content_location, outer_size=outer_size, inner_size=inner_size, parent_scroll_position=original_location, scroll_root_element=scroll_root_element, ) self._driver.frame_chain.push(frame)
def __init__(self, image, location=None): super(EyesImagesScreenshot, self).__init__(image) if location is None: location = Point.zero() argument_guard.is_a(location, Point) self._location = location self._bounds = Region.from_( location, dict(width=self._image.width, height=self._image.height) )
def location(self): # type: () -> Point loc = Point.from_( super(MobileSafariElementAdapter, self).location) # scroll into view at this point curr_pos = eyes_selenium_utils.get_current_position( self._eyes_driver, eyes_selenium_utils.scroll_root_element_from(self._eyes_driver), ) return loc + curr_pos
def _get_viewport_scroll_bounds(self): switch_to = self.driver.switch_to with switch_to.frames_and_back(self._original_fc): try: location = eyes_selenium_utils.get_current_position( self.driver, self.scroll_root_element) except WebDriverException as e: logger.warning(str(e)) logger.info("Assuming position is 0,0") location = Point(0, 0) viewport_bounds = Region.from_(location, self._get_viewport_size()) return viewport_bounds
def _get_viewport_scroll_bounds(self): switch_to = self.driver.switch_to with switch_to.frames_and_back(self.original_frame_chain): try: location = ScrollPositionProvider.get_current_position_static( self.driver, self.scroll_root_element) except WebDriverException as e: logger.warning(str(e)) logger.info("Assuming position is 0,0") location = Point(0, 0) viewport_bounds = Region.from_location_size(location, self._get_viewport_size()) return viewport_bounds
def collect_regions_from_selectors(image_match_settings, regions, region_selectors): # type:(ImageMatchSettings,List[Region],List[List[VisualGridSelector]])->ImageMatchSettings if not regions: return image_match_settings mutable_regions = [ [], # Ignore Regions [], # Layout Regions [], # Strict Regions [], # Content Regions [], # Floating Regions [], # Target Element Location ] r_selector_counts = [len(r) for r in region_selectors] # mapping of prev_count = 0 for selectors_count, m_specific_regions in zip(r_selector_counts, mutable_regions): if selectors_count == 0: continue next_count = prev_count + selectors_count m_specific_regions.extend(regions[prev_count:next_count]) prev_count = next_count location = Point.ZERO() # If target element location available selector_regions_index = len(mutable_regions) - 1 if mutable_regions[selector_regions_index]: location = mutable_regions[selector_regions_index][0].location image_match_settings.ignore_regions = filter_empty_entries( mutable_regions[0], location) image_match_settings.layout_regions = filter_empty_entries( mutable_regions[1], location) image_match_settings.strict_regions = filter_empty_entries( mutable_regions[2], location) image_match_settings.content_regions = filter_empty_entries( mutable_regions[3], location) floating_match_settings = [] for i, reg in enumerate(mutable_regions[4]): if reg.area == 0: continue vgs = region_selectors[4][i] gfr = vgs.category if isinstance(gfr, GetFloatingRegion): fms = FloatingMatchSettings(reg, gfr.bounds) floating_match_settings.append(fms) image_match_settings.floating_match_settings = floating_match_settings return image_match_settings
def _ensure_element_visible(self, element): position_provider = fc = None if element and not self.driver.is_mobile_app: original_fc = self.driver.frame_chain.clone() element_bounds = element.bounds current_frame_offset = original_fc.current_frame_offset element_bounds = element_bounds.offset(current_frame_offset) viewport_bounds = self._get_viewport_scroll_bounds() logger.info( "viewport_bounds: {}; element_bounds: {}".format( viewport_bounds, element_bounds ) ) if not viewport_bounds.contains(element_bounds): self._ensure_frame_visible() element_location = Point.from_(element.location) if len(original_fc) > 0 and element is not original_fc.peek.reference: fc = original_fc self.driver.switch_to.frames(original_fc) scroll_root_element = ( eyes_selenium_utils.curr_frame_scroll_root_element( self.driver, self._scroll_root_element ) ) # This might happen when scroll root element is calculated in the # beginning of SeleniumEyes.check when there is a frame in # driver's frame_chain but it gets popped out and becomes check target elif not self.scroll_root_element.is_attached_to_page: fc = self.driver.frame_chain.clone() scroll_root_element = self.driver.find_element_by_tag_name("html") else: fc = self.driver.frame_chain.clone() scroll_root_element = self.scroll_root_element position_provider = self._element_position_provider_from( scroll_root_element ) state = position_provider.get_state() position_provider.set_position(element_location) yield position_provider if element and position_provider and fc and not self.driver.is_mobile_app: self.driver.switch_to.frames(fc) position_provider.restore_state(state)
def collect_regions_from_selectors(image_match_settings, regions, region_selectors): # type:(ImageMatchSettings,List[Region],List[List[VisualGridSelector]])->ImageMatchSettings if not regions: return image_match_settings logger.debug(""" start collect_regions_from_selectors() regions: {} region_selectors: {} """.format(regions, region_selectors)) mutable_regions = [ [], # Ignore Regions [], # Layout Regions [], # Strict Regions [], # Content Regions [], # Floating Regions [], # Accessibility Regions [], # Target Element Location ] r_selector_counts = [len(r) for r in region_selectors] # mapping of prev_count = 0 for i, (selectors_count, m_specific_regions) in enumerate( zip(r_selector_counts, mutable_regions)): if selectors_count == 0: continue next_count = prev_count + selectors_count for region_selector, region in zip(region_selectors[i], regions[prev_count:next_count]): padding = getattr(region_selector.category, "padding", None) if padding: region = region.padding(padding) m_specific_regions.append(region) prev_count = next_count location = Point.ZERO() # If target element location available selector_regions_index = len(mutable_regions) - 1 if mutable_regions[selector_regions_index]: location = mutable_regions[selector_regions_index][0].location image_match_settings.ignore_regions = filter_empty_entries( mutable_regions[0], location) image_match_settings.layout_regions = filter_empty_entries( mutable_regions[1], location) image_match_settings.strict_regions = filter_empty_entries( mutable_regions[2], location) image_match_settings.content_regions = filter_empty_entries( mutable_regions[3], location) image_match_settings.floating_match_settings = [ FloatingMatchSettings(reg, gfr.floating_bounds) for (reg, gfr) in filter_empty_entries_and_combine( mutable_regions[4], location, region_selectors[4]) if isinstance(gfr, GetFloatingRegion) ] image_match_settings.accessibility = [ AccessibilityRegion.from_(reg, gfr.accessibility_type) for (reg, gfr) in filter_empty_entries_and_combine( mutable_regions[5], location, region_selectors[5]) if isinstance(gfr, GetAccessibilityRegion) ] logger.debug(""" finish collect_regions_from_selectors() image_match_settings: {} """.format(image_match_settings)) return image_match_settings
def get_window_position(self, windowHandle="current"): loc = self._driver.get_window_position(windowHandle) return Point(**loc)