Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Copyright 2016 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 import environment | |
| 6 import logging | |
| 7 import os | |
| 8 import pyautogui | |
| 9 import time | |
| 10 | |
| 11 from PIL import Image | |
| 12 from selenium.webdriver.common.action_chains import ActionChains | |
| 13 | |
| 14 SCRIPT_DEBUG = 100 | |
| 15 | |
| 16 class ScreenshotGenerator: | |
| 17 """Base class for creation of screenshots providing utility functions.""" | |
| 18 | |
| 19 def __init__(self, name): | |
| 20 """Creates a new ScreenshotGenerator instance. | |
| 21 | |
| 22 Args: | |
| 23 name: The name of the screenshot type. | |
| 24 """ | |
| 25 self.name = name | |
| 26 | |
| 27 # The Environment, if added to any. | |
| 28 self.environment = None | |
| 29 # The webdriver from the environment. | |
| 30 self.driver = None | |
| 31 | |
| 32 # Mouse/Keyboard actions. | |
| 33 | |
| 34 def Click(self, selector): | |
| 35 """Clicks on the element described by |selector|. | |
| 36 | |
| 37 Args: | |
| 38 selector: The clicked element's CSS selector. | |
| 39 """ | |
| 40 | |
| 41 logging.log(SCRIPT_DEBUG, "action: Click %s" % selector) | |
|
melandory
2016/05/30 13:51:49
nit:
since it's python and you're using same patte
| |
| 42 element = self.WaitUntilDisplayed(selector) | |
| 43 element.click() | |
| 44 | |
| 45 def ClickIfClickable(self, selector): | |
| 46 """Clicks on the element described by |selector| if it is clickable. | |
| 47 | |
| 48 The driver's find_element_by_css_selector method defines what is clickable | |
| 49 -- anything for which it does not throw, is clickable. To be clickable, | |
| 50 the element must: | |
| 51 * exist in the DOM, | |
| 52 * be not covered by another element | |
| 53 * be inside the visible area. | |
| 54 Note that transparency does not influence clickability. | |
| 55 | |
| 56 Args: | |
| 57 selector: The clicked element's CSS selector. | |
| 58 | |
| 59 Returns: | |
| 60 True if the element is clickable (and was clicked on). | |
| 61 False otherwise. | |
| 62 """ | |
| 63 | |
| 64 logging.log(SCRIPT_DEBUG, "action: ClickIfVisible %s" % selector) | |
| 65 element = self.WaitUntilDisplayed(selector) | |
| 66 try: | |
| 67 element.click() | |
| 68 return True | |
| 69 except Exception: | |
| 70 return False | |
| 71 | |
| 72 def GoTo(self, url): | |
| 73 """Navigates the main frame to |url|. | |
| 74 | |
| 75 Args: | |
| 76 url: The URL of where to go to. | |
| 77 """ | |
| 78 | |
| 79 logging.log(SCRIPT_DEBUG, "action: GoTo %s" % self.name) | |
| 80 self.driver.get(url) | |
| 81 | |
| 82 def HoverOver(self, selector): | |
| 83 """Hovers over the element described by |selector|. | |
| 84 | |
| 85 Args: | |
| 86 selector: The CSS selector of the element to hover over. | |
| 87 """ | |
| 88 | |
| 89 logging.log(SCRIPT_DEBUG, "action: Hover %s" % selector) | |
| 90 element = self.WaitUntilDisplayed(selector) | |
| 91 hover = ActionChains(self.driver).move_to_element(element) | |
| 92 hover.perform() | |
| 93 | |
| 94 # Waiting/Displaying actions. | |
| 95 | |
| 96 def _ReturnElementIfDisplayed(self, selector): | |
| 97 """Returns the element described by |selector|, if displayed. | |
| 98 | |
| 99 Note: This takes neither overlapping among elements nor position with | |
| 100 regards to the visible area into account. | |
| 101 | |
| 102 Args: | |
| 103 selector: The CSS selector of the checked element. | |
| 104 | |
| 105 Returns: | |
| 106 The element if displayed, None otherwise. | |
| 107 """ | |
| 108 | |
| 109 try: | |
| 110 element = self.driver.find_element_by_css_selector(selector) | |
| 111 if element: | |
| 112 logging.log(SCRIPT_DEBUG, "Found element %s" % selector) | |
| 113 else: | |
| 114 logging.log(SCRIPT_DEBUG, "Did not find element %s" % selector) | |
| 115 return element if element.is_displayed() else None | |
| 116 except Exception as e: | |
| 117 logging.log(SCRIPT_DEBUG, "Exception %s", e) | |
| 118 return None | |
| 119 | |
| 120 def IsDisplayed(self, selector): | |
| 121 """Check if the element described by |selector| is displayed. | |
| 122 | |
| 123 Note: This takes neither overlapping among elements nor position with | |
| 124 regards to the visible area into account. | |
| 125 | |
| 126 Args: | |
| 127 selector: The CSS selector of the checked element. | |
| 128 | |
| 129 Returns: | |
| 130 True if the element is in the DOM and less than 100% transparent. | |
| 131 False otherwise. | |
| 132 """ | |
| 133 | |
| 134 logging.log(SCRIPT_DEBUG, "action: IsDisplayed %s" % selector) | |
| 135 return self._ReturnElementIfDisplayed(selector) is not None | |
| 136 | |
| 137 def Wait(self, duration): | |
| 138 """Wait for |duration| in seconds. | |
| 139 | |
| 140 Args: | |
| 141 duration: The time to wait in seconds. | |
| 142 | |
| 143 Raises: | |
| 144 Exception: In case the accummulated waiting limit is exceeded. | |
| 145 """ | |
| 146 | |
| 147 logging.log(SCRIPT_DEBUG, "action: Wait %s" % duration) | |
| 148 time.sleep(duration) | |
| 149 | |
| 150 def WaitUntilDisplayed(self, selector): | |
| 151 """Waits until the element described by |selector| is displayed. | |
| 152 | |
| 153 Args: | |
| 154 selector: The CSS selector of the element to wait for. | |
| 155 | |
| 156 Returns: | |
| 157 The displayed element. | |
| 158 """ | |
| 159 | |
| 160 element = self._ReturnElementIfDisplayed(selector) | |
| 161 while not element: | |
| 162 logging.log(SCRIPT_DEBUG, "action: Waiting for %s to show up" % selector) | |
| 163 self.Wait(1) | |
| 164 element = self._ReturnElementIfDisplayed(selector) | |
| 165 return element | |
| 166 | |
| 167 def CaptureContentScreenshot(self, selector): | |
| 168 """Waits until the element is displayed and captures a screenshot of it. | |
| 169 | |
| 170 The screenshot is written to self.environment.output_path. | |
| 171 | |
| 172 Args: | |
| 173 selector: The CSS selector of the element to take a picture of. | |
| 174 """ | |
| 175 | |
| 176 filename = "%s-%s.png" % (self.name, self.environment.language) | |
| 177 final_path = os.path.join(self.environment.output_path, filename) | |
| 178 tmp_path = os.path.join(self.environment.output_path, "tmp.png") | |
| 179 logging.log(SCRIPT_DEBUG, "Storing a screenshot to %s", final_path) | |
| 180 | |
| 181 self.HoverOver(selector) | |
| 182 element = self.WaitUntilDisplayed(selector) | |
| 183 location, size = element.location_once_scrolled_into_view, element.size | |
| 184 x, y = location['x'], location['y'] | |
| 185 w, h = size['width'], size['height'] | |
| 186 self.driver.save_screenshot(tmp_path) | |
| 187 img = Image.open(tmp_path) | |
| 188 img = img.crop((x, y, x + w, y + h)) | |
| 189 img.save(final_path, 'png') | |
| 190 os.remove(tmp_path) | |
| 191 | |
| 192 def CaptureWindowScreenshot(self, top=0, bottom=0, left=0, right=0): | |
| 193 """Takes a screenshot of the top/bottom/left/right pixels of the browser | |
| 194 window. | |
| 195 | |
| 196 This requires that the browser window is positioned on the top left of the | |
| 197 screen. | |
| 198 | |
| 199 Args: | |
| 200 top: Number of pixel rows to take a screenshot of. | |
| 201 bottom: Number of pixel rows to take a screenshot of. | |
| 202 left: Number of pixel columns to take a screenshot of. | |
| 203 right: Number of pixel columns to take a screenshot of. | |
| 204 """ | |
| 205 filename = "%s-%s.png" % (self.name, self.environment.language) | |
| 206 final_path = os.path.join(self.environment.output_path, filename) | |
| 207 tmp_path = os.path.join(self.environment.output_path, "tmp.png") | |
| 208 | |
| 209 im = pyautogui.screenshot() | |
| 210 im.save(tmp_path) | |
| 211 | |
| 212 img = Image.open(tmp_path) | |
| 213 img = img.crop((0, 0, self.driver.get_window_size()['width'], | |
| 214 self.driver.get_window_size()['height'])) | |
| 215 if top != 0: | |
| 216 img = img.crop((0, 0, img.size[0], top)) | |
| 217 if bottom != 0: | |
| 218 img = img.crop((0, img.size[1] - bottom, img.size[0], img.size[1])) | |
| 219 if left != 0: | |
| 220 img = img.crop((0, 0, left, img.size[1])) | |
| 221 if right != 0: | |
| 222 img = img.crop((img.size[0] - right, 0, img.size[0], img.size[1])) | |
| 223 img.save(final_path, 'png') | |
| 224 os.remove(tmp_path) | |
| OLD | NEW |