| # Copyright 2017 The Chromium OS 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 glob |
| import logging |
| import os |
| import utils |
| |
| from autotest_lib.client.common_lib import error |
| from autotest_lib.client.common_lib.cros import chrome |
| from autotest_lib.client.cros.enterprise import enterprise_policy_base |
| from autotest_lib.client.cros.input_playback import input_playback |
| |
| POLL_TIMEOUT = 5 |
| POLL_FREQUENCY = 0.5 |
| |
| |
| class policy_DisableScreenshots( |
| enterprise_policy_base.EnterprisePolicyTest): |
| version = 1 |
| |
| def initialize(self, **kwargs): |
| """Emulate a keyboard in order to play back the screenshot shortcut.""" |
| self._initialize_test_constants() |
| super(policy_DisableScreenshots, self).initialize(**kwargs) |
| self.player = input_playback.InputPlayback() |
| self.player.emulate(input_type='keyboard') |
| self.player.find_connected_inputs() |
| |
| |
| def _initialize_test_constants(self): |
| """Initialize test-specific constants, some from class constants.""" |
| self.POLICY_NAME = 'DisableScreenshots' |
| self._DOWNLOADS = '/home/chronos/user/Downloads/' |
| self._SCREENSHOT_PATTERN = 'Screenshot*' |
| self._SCREENSHOT_FILENAME = self._DOWNLOADS + self._SCREENSHOT_PATTERN |
| |
| self.TEST_CASES = { |
| 'DisableScreenshot_Block': True, |
| 'False_Allow': False, |
| 'NotSet_Allow': None |
| } |
| |
| # Possible API methods to capture the screen |
| self.CAPTURE_CMDS = [ |
| 'captureVisibleTab', |
| # TODO(timkovich): https://crbug.com/839630 |
| # 'tabCapture', |
| # TODO(timkovich): https://crbug.com/817497 |
| # 'desktopCapture' |
| ] |
| |
| |
| def _screenshot_file_exists(self): |
| """ |
| Checks if screenshot file was created by keyboard shortcut. |
| |
| @returns boolean indicating if screenshot file was saved or not. |
| |
| """ |
| try: |
| utils.poll_for_condition( |
| lambda: len(glob.glob(self._SCREENSHOT_FILENAME)) > 0, |
| timeout=POLL_TIMEOUT, |
| sleep_interval=POLL_FREQUENCY) |
| except utils.TimeoutError: |
| logging.info('Screenshot file not found.') |
| return False |
| |
| logging.info('Screenshot file found.') |
| return True |
| |
| |
| def _delete_screenshot_files(self): |
| """Delete existing screenshot files, if any.""" |
| for filename in glob.glob(self._SCREENSHOT_FILENAME): |
| os.remove(filename) |
| |
| |
| def cleanup(self): |
| """Cleanup files created in this test, if any and close the player.""" |
| self._delete_screenshot_files() |
| self.player.close() |
| super(policy_DisableScreenshots, self).cleanup() |
| |
| |
| def _test_screenshot_shortcut(self, policy_value): |
| """ |
| Verify DisableScreenshots is enforced for the screenshot shortcut. |
| |
| When DisableScreenshots policy value is undefined, screenshots shall |
| be captured via the keyboard shortcut Ctrl + F5. |
| When DisableScreenshots policy is set to True screenshots shall not |
| be captured. |
| |
| @param policy_value: policy value for this case. |
| |
| """ |
| logging.info('Deleting preexisting Screenshot files.') |
| self._delete_screenshot_files() |
| |
| # Keyboard shortcut for screenshots |
| self.player.blocking_playback_of_default_file( |
| input_type='keyboard', filename='keyboard_ctrl+f5') |
| |
| screenshot_file_captured = self._screenshot_file_exists() |
| if policy_value: |
| if screenshot_file_captured: |
| raise error.TestFail('Screenshot should not be captured') |
| elif not screenshot_file_captured: |
| raise error.TestFail('Screenshot should be captured') |
| |
| |
| def _test_screenshot_apis(self, policy_value): |
| """ |
| Verify DisableScreenshot policy blocks API calls. |
| |
| Attempts to capture the screen using all of the methods to capture |
| the screen through the APIs. Captures should not happen when |
| policy_value is True and should happen in the other cases. |
| |
| @param policy_value: policy value for this case |
| |
| @raises error.TestFail: In the case where the capture behavior |
| does not match the policy value |
| |
| """ |
| tab = self.navigate_to_url('https://google.com') |
| |
| current_dir = os.path.dirname(os.path.realpath(__file__)) |
| |
| for method in self.CAPTURE_CMDS: |
| # Set the document.title to the test name |
| tab.ExecuteJavaScript('document.title = "%s"' % method) |
| |
| # Call the extension's shortcut to trigger the API call |
| self.player.blocking_playback( |
| input_type='keyboard', |
| filepath=os.path.join(current_dir, 'keyboard_ctrl+shift+y')) |
| |
| # desktopCapture opens a prompt window that needs to be OKed |
| if method == 'desktopCapture': |
| self.player.blocking_playback_of_default_file( |
| input_type='keyboard', filename='keyboard_enter') |
| |
| # The document.title is used to pass information to and from |
| # the DOM and the extension. The return value of the screenshot |
| # API call is set to the document.title. |
| try: |
| utils.poll_for_condition( |
| lambda: tab.EvaluateJavaScript( |
| 'document.title != "%s"' % method |
| ), |
| timeout=POLL_TIMEOUT) |
| capture = tab.EvaluateJavaScript('document.title') |
| except utils.TimeoutError: |
| capture = None |
| |
| if capture == 'undefined': |
| capture = None |
| |
| if policy_value: |
| if capture is not None: |
| raise error.TestFail('Screen should not be captured. ' |
| 'method = %s, capture = %s' |
| % (method, capture)) |
| elif capture is None: |
| raise error.TestFail('Screen should be captured. ' |
| 'method = %s, capture = %s' |
| % (method, capture)) |
| |
| |
| def run_once(self, case): |
| """ |
| Setup and run the test configured for the specified test case. |
| |
| @param case: Name of the test case to run. |
| |
| """ |
| case_value = self.TEST_CASES[case] |
| self._extension_path = os.path.join(os.path.dirname(__file__), |
| 'Screenshooter') |
| |
| self.setup_case(user_policies={self.POLICY_NAME: case_value}, |
| extension_paths=[self._extension_path]) |
| |
| self._test_screenshot_shortcut(case_value) |
| self._test_screenshot_apis(case_value) |