# 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 datetime import logging import os import random import tempfile from py_utils import cloud_storage # pylint: disable=import-error from telemetry.util import image_util from telemetry.internal.util import file_handle def TryCaptureScreenShot(platform, tab=None): """ If the platform or tab supports screenshot, attempt to take a screenshot of the current browser. Args: platform: current platform tab: browser tab if available Returns: file handle of the tempoerary file path for the screenshot if present, None otherwise. """ try: # TODO(nednguyen): once all platforms support taking screenshot, # remove the tab checking logic and consider moving this to story_runner. # (crbug.com/369490) if platform.CanTakeScreenshot(): tf = tempfile.NamedTemporaryFile(delete=False, suffix='.png') tf.close() platform.TakeScreenshot(tf.name) return file_handle.FromTempFile(tf) elif tab and tab.IsAlive() and tab.screenshot_supported: tf = tempfile.NamedTemporaryFile(delete=False, suffix='.png') tf.close() image = tab.Screenshot() image_util.WritePngFile(image, tf.name) return file_handle.FromTempFile(tf) else: logging.warning( 'Either tab has crashed or browser does not support taking tab ' 'screenshot. Skip taking screenshot on failure.') return None except Exception as e: logging.warning('Exception when trying to capture screenshot: %s', repr(e)) return None def TryCaptureScreenShotAndUploadToCloudStorage(platform, tab=None): """ If the platform or tab supports screenshot, attempt to take a screenshot of the current browser. If present it uploads this local path to cloud storage and returns the URL of the cloud storage path. Args: platform: current platform tab: browser tab if available Returns: url of the cloud storage path if screenshot is present, None otherwise """ fh = TryCaptureScreenShot(platform, tab) if fh is not None: return _UploadScreenShotToCloudStorage(fh) return None def _GenerateRemotePath(fh): return ('browser-screenshot_%s-%s%-d%s' % ( fh.id, datetime.datetime.now().strftime('%Y-%m-%d_%H-%M-%S'), random.randint(1, 100000), fh.extension)) def _UploadScreenShotToCloudStorage(fh): """ Upload the given screenshot image to cloud storage and return the cloud storage url if successful. """ try: return cloud_storage.Insert(cloud_storage.TELEMETRY_OUTPUT, _GenerateRemotePath(fh), fh.GetAbsPath()) except cloud_storage.CloudStorageError as err: logging.error('Cloud storage error while trying to upload screenshot: %s' % repr(err)) return '' finally: # Must clean up screenshot file if exists. os.remove(fh.GetAbsPath())