Index: tools/privacy_whitepaper/screenshot_generator.py |
diff --git a/tools/privacy_whitepaper/screenshot_generator.py b/tools/privacy_whitepaper/screenshot_generator.py |
new file mode 100644 |
index 0000000000000000000000000000000000000000..3fe057df414a6b1ec2bf9c8ba267bbef4131cd20 |
--- /dev/null |
+++ b/tools/privacy_whitepaper/screenshot_generator.py |
@@ -0,0 +1,224 @@ |
+# Copyright 2016 The Chromium Authors. All rights reserved. |
+# Use of this source code is governed by a BSD-style license that can be |
+# found in the LICENSE file. |
+ |
+import environment |
+import logging |
+import os |
+import pyautogui |
+import time |
+ |
+from PIL import Image |
+from selenium.webdriver.common.action_chains import ActionChains |
+ |
+SCRIPT_DEBUG = 100 |
+ |
+class ScreenshotGenerator: |
+ """Base class for creation of screenshots providing utility functions.""" |
+ |
+ def __init__(self, name): |
+ """Creates a new ScreenshotGenerator instance. |
+ |
+ Args: |
+ name: The name of the screenshot type. |
+ """ |
+ self.name = name |
+ |
+ # The Environment, if added to any. |
+ self.environment = None |
+ # The webdriver from the environment. |
+ self.driver = None |
+ |
+ # Mouse/Keyboard actions. |
+ |
+ def Click(self, selector): |
+ """Clicks on the element described by |selector|. |
+ |
+ Args: |
+ selector: The clicked element's CSS selector. |
+ """ |
+ |
+ 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
|
+ element = self.WaitUntilDisplayed(selector) |
+ element.click() |
+ |
+ def ClickIfClickable(self, selector): |
+ """Clicks on the element described by |selector| if it is clickable. |
+ |
+ The driver's find_element_by_css_selector method defines what is clickable |
+ -- anything for which it does not throw, is clickable. To be clickable, |
+ the element must: |
+ * exist in the DOM, |
+ * be not covered by another element |
+ * be inside the visible area. |
+ Note that transparency does not influence clickability. |
+ |
+ Args: |
+ selector: The clicked element's CSS selector. |
+ |
+ Returns: |
+ True if the element is clickable (and was clicked on). |
+ False otherwise. |
+ """ |
+ |
+ logging.log(SCRIPT_DEBUG, "action: ClickIfVisible %s" % selector) |
+ element = self.WaitUntilDisplayed(selector) |
+ try: |
+ element.click() |
+ return True |
+ except Exception: |
+ return False |
+ |
+ def GoTo(self, url): |
+ """Navigates the main frame to |url|. |
+ |
+ Args: |
+ url: The URL of where to go to. |
+ """ |
+ |
+ logging.log(SCRIPT_DEBUG, "action: GoTo %s" % self.name) |
+ self.driver.get(url) |
+ |
+ def HoverOver(self, selector): |
+ """Hovers over the element described by |selector|. |
+ |
+ Args: |
+ selector: The CSS selector of the element to hover over. |
+ """ |
+ |
+ logging.log(SCRIPT_DEBUG, "action: Hover %s" % selector) |
+ element = self.WaitUntilDisplayed(selector) |
+ hover = ActionChains(self.driver).move_to_element(element) |
+ hover.perform() |
+ |
+ # Waiting/Displaying actions. |
+ |
+ def _ReturnElementIfDisplayed(self, selector): |
+ """Returns the element described by |selector|, if displayed. |
+ |
+ Note: This takes neither overlapping among elements nor position with |
+ regards to the visible area into account. |
+ |
+ Args: |
+ selector: The CSS selector of the checked element. |
+ |
+ Returns: |
+ The element if displayed, None otherwise. |
+ """ |
+ |
+ try: |
+ element = self.driver.find_element_by_css_selector(selector) |
+ if element: |
+ logging.log(SCRIPT_DEBUG, "Found element %s" % selector) |
+ else: |
+ logging.log(SCRIPT_DEBUG, "Did not find element %s" % selector) |
+ return element if element.is_displayed() else None |
+ except Exception as e: |
+ logging.log(SCRIPT_DEBUG, "Exception %s", e) |
+ return None |
+ |
+ def IsDisplayed(self, selector): |
+ """Check if the element described by |selector| is displayed. |
+ |
+ Note: This takes neither overlapping among elements nor position with |
+ regards to the visible area into account. |
+ |
+ Args: |
+ selector: The CSS selector of the checked element. |
+ |
+ Returns: |
+ True if the element is in the DOM and less than 100% transparent. |
+ False otherwise. |
+ """ |
+ |
+ logging.log(SCRIPT_DEBUG, "action: IsDisplayed %s" % selector) |
+ return self._ReturnElementIfDisplayed(selector) is not None |
+ |
+ def Wait(self, duration): |
+ """Wait for |duration| in seconds. |
+ |
+ Args: |
+ duration: The time to wait in seconds. |
+ |
+ Raises: |
+ Exception: In case the accummulated waiting limit is exceeded. |
+ """ |
+ |
+ logging.log(SCRIPT_DEBUG, "action: Wait %s" % duration) |
+ time.sleep(duration) |
+ |
+ def WaitUntilDisplayed(self, selector): |
+ """Waits until the element described by |selector| is displayed. |
+ |
+ Args: |
+ selector: The CSS selector of the element to wait for. |
+ |
+ Returns: |
+ The displayed element. |
+ """ |
+ |
+ element = self._ReturnElementIfDisplayed(selector) |
+ while not element: |
+ logging.log(SCRIPT_DEBUG, "action: Waiting for %s to show up" % selector) |
+ self.Wait(1) |
+ element = self._ReturnElementIfDisplayed(selector) |
+ return element |
+ |
+ def CaptureContentScreenshot(self, selector): |
+ """Waits until the element is displayed and captures a screenshot of it. |
+ |
+ The screenshot is written to self.environment.output_path. |
+ |
+ Args: |
+ selector: The CSS selector of the element to take a picture of. |
+ """ |
+ |
+ filename = "%s-%s.png" % (self.name, self.environment.language) |
+ final_path = os.path.join(self.environment.output_path, filename) |
+ tmp_path = os.path.join(self.environment.output_path, "tmp.png") |
+ logging.log(SCRIPT_DEBUG, "Storing a screenshot to %s", final_path) |
+ |
+ self.HoverOver(selector) |
+ element = self.WaitUntilDisplayed(selector) |
+ location, size = element.location_once_scrolled_into_view, element.size |
+ x, y = location['x'], location['y'] |
+ w, h = size['width'], size['height'] |
+ self.driver.save_screenshot(tmp_path) |
+ img = Image.open(tmp_path) |
+ img = img.crop((x, y, x + w, y + h)) |
+ img.save(final_path, 'png') |
+ os.remove(tmp_path) |
+ |
+ def CaptureWindowScreenshot(self, top=0, bottom=0, left=0, right=0): |
+ """Takes a screenshot of the top/bottom/left/right pixels of the browser |
+ window. |
+ |
+ This requires that the browser window is positioned on the top left of the |
+ screen. |
+ |
+ Args: |
+ top: Number of pixel rows to take a screenshot of. |
+ bottom: Number of pixel rows to take a screenshot of. |
+ left: Number of pixel columns to take a screenshot of. |
+ right: Number of pixel columns to take a screenshot of. |
+ """ |
+ filename = "%s-%s.png" % (self.name, self.environment.language) |
+ final_path = os.path.join(self.environment.output_path, filename) |
+ tmp_path = os.path.join(self.environment.output_path, "tmp.png") |
+ |
+ im = pyautogui.screenshot() |
+ im.save(tmp_path) |
+ |
+ img = Image.open(tmp_path) |
+ img = img.crop((0, 0, self.driver.get_window_size()['width'], |
+ self.driver.get_window_size()['height'])) |
+ if top != 0: |
+ img = img.crop((0, 0, img.size[0], top)) |
+ if bottom != 0: |
+ img = img.crop((0, img.size[1] - bottom, img.size[0], img.size[1])) |
+ if left != 0: |
+ img = img.crop((0, 0, left, img.size[1])) |
+ if right != 0: |
+ img = img.crop((img.size[0] - right, 0, img.size[0], img.size[1])) |
+ img.save(final_path, 'png') |
+ os.remove(tmp_path) |