190 lines
6.8 KiB
Python
190 lines
6.8 KiB
Python
# 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)
|