blob: 4dc1944baa838c4b6753a773ddb0aa1f0134b35a [file] [log] [blame]
#!/usr/bin/env python
#
# Copyright 2017 Google Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Runs all Franky test cases for a given channel."""
import argparse
import logging
import os
from actions import system
from appium_util import appium_driver_util
from appium_util import path_constants
import device_info
import download_testcases_csv
import oauth2client.tools as tools
from test_util import franky_testsuite
from utilities import gsutil_download
from utilities import util
# App file extensions.
_APP_EXTENSION = {
appium_driver_util.IOS: '.app',
appium_driver_util.ANDROID: '.apk',
}
# A list to keep track of temporary files created.
_TEMPFILES = util.TempFiles()
# Prefix of Monochrome[Canary|Dev|Beta|Stable].apk.
_PREFIX_MONOCHROME = 'Monochrome'
def _ParseArgs(passed_args=None):
"""Parses the command line arguments.
Args:
passed_args: a list of args.
Returns:
The parsed commandline arguments.
"""
html = gsutil_download.HTML
json = gsutil_download.JSON
arg_parser = argparse.ArgumentParser(
description='Runs Franky test cases on a Chrome Channel.',
parents=[tools.argparser])
arg_parser.add_argument(
'channel',
choices=[
path_constants.BETA, path_constants.CANARY, path_constants.DEV,
path_constants.STABLE
],
help='The Chrome channel to run test cases against.')
arg_parser.add_argument(
'platform',
choices=[appium_driver_util.IOS, appium_driver_util.ANDROID],
help='The platform to run tests against.')
arg_parser.add_argument(
'-i',
'--app-intent',
default=None,
help='A string specifying which intent to use.')
arg_parser.add_argument(
'-a',
'--app-path',
help='The full path to the .app bundle to be tested. '
'The default location is the current directory.')
arg_parser.add_argument(
'--appium-command',
default=appium_driver_util.ChooseAppiumClient(),
help='The command to invoke appium server. A special value of NONE '
'disables Appium invocation and relies on an already running server. '
'Default: "%(default)s".')
arg_parser.add_argument(
'-s',
'--appium-dir-path',
default=appium_driver_util.ChooseAppiumDirPath(),
help='The full path to appium server directory. A special value NONE '
'will keep it unset. The default location is %(default)s.')
arg_parser.add_argument(
'-p',
'--package-pull',
help='The package name of installed apk on the device '
'that will be pulled.')
arg_parser.add_argument(
'-c',
'--copy-to-cloud-storage',
action='store_true',
default=False,
help='Copy generated HTML reports to '
'Google Cloud Storage. Run "gcloud auth" before'
' first use.')
arg_parser.add_argument(
'--prerun-script',
default=None,
help='A string set in quotes of a script with arguments to be ran prior'
' to test execution.')
arg_parser.add_argument(
'-gs',
'--gsutil-download',
default=None,
help='A version of Chrome to download or "Latest."')
arg_parser.add_argument(
'-d',
'--host-address',
action='store_true',
default='127.0.0.1',
help='Default Host for Appium '
'server.')
arg_parser.add_argument(
'--appium-port',
default='4723',
help='Port for Appium server.')
arg_parser.add_argument(
'-n',
'--no-retry',
action='store_true',
default=False,
help='Do not rerun a test.'
'If not set, a test will rerun after it fails.')
arg_parser.add_argument(
'-r',
'--report-format',
choices=[html, json],
default=html,
help='Generate a json or html report '
'out of the test results.')
arg_parser.add_argument(
'-sc',
'--screen-capture',
action='store_true',
default=False,
help='Store screenshots with failures or not. Default is False.')
arg_parser.add_argument(
'--skip-reset',
action='store_true',
default=False,
help='Do not reset app between '
'test cases.')
arg_parser.add_argument(
'-f',
'--test-filter',
default=None,
help='A comma separated string of numbers indicating'
' which tests to run in the suite.')
arg_parser.add_argument(
'-t',
'--test-suite',
action='append',
help='Test suite file(s) to run; can be a glob. Multiple arguments '
'add up. Default are all files matching "*<channel>*.csv" in CWD.'
'File type is determined by extension: .csv is CSV, .txt is text proto.')
arg_parser.add_argument(
'--report-folder',
default=None,
help='The full path to the directory where report will store. '
'If not specified, folder of 1st test_suite will be report_folder.')
arg_parser.add_argument(
'--csv',
default=None,
help='Download the specified workbook as a CSV file. To download multiple'
'workbooks use comma as delimiter. The format of parameter is'
'"spreadsheet_key, workbook_id1,..., workbook_idN"')
arg_parser.add_argument(
'--use-prebuilt-wda',
action='store_true',
default=False,
help='Do not rebuild the WebDriverAgent app.')
arg_parser.add_argument(
'-ui2',
'--use-uiautomator2',
action='store_true',
default=False,
help='Use uiautomator2.')
arg_parser.add_argument(
'-v',
'--verbose',
action='store_true',
default=False,
help='Increase test output verbosity.')
arg_parser.add_argument(
'--webview',
action='store_true',
default=False,
help='Run webview test setup steps.')
arg_parser.add_argument(
'--xcconfig',
metavar='FILE',
help='XCode config for xcodebuild launching WDA.')
arg_parser.add_argument(
'-id', '--device-id', help='The device ID/serial number to run test on.')
arg_parser.add_argument(
'-flags', '--exp-flags', action='append',
help='[iOS ONLY] List of command line flags that need to be '
'enabled/disabled before launching the Chrome App'
'Example1: -flags=--enable-features=F1,F2'
'Example2: -flags=--enabled-features=F1,--disable-features=F2')
args = arg_parser.parse_args(passed_args)
if args.platform == appium_driver_util.ANDROID:
devices = util.GetAndroidDeviceSerialNumbers()
elif args.platform == appium_driver_util.IOS:
devices = util.GetIOSDeviceUDIDNumbers()
if not devices:
logging.error('No device connected to machine')
elif not args.device_id:
args.device_id = devices[0]
elif args.device_id not in devices:
logging.error('Device with ID %s not found in connected devices %s' %
(args.device_id, devices))
if args.appium_command == 'NONE':
args.appium_command = None
else:
args.appium_command = args.appium_command.split(' ')
if args.appium_dir_path == 'NONE':
args.appium_dir_path = None
webview_package = system.CHANNEL_TO_WEBVIEW_PACKAGE[args.channel]
if args.prerun_script:
util.ExecuteProcess(util.ExpandPaths(args.prerun_script.split(' ')))
# TODO(bjoyce): Remove when prerun script works for webview.
if args.gsutil_download:
if args.webview:
webview_apk = gsutil_download.DownloadAndroidApp(
args.gsutil_download, args.channel, args.device_id, True)
# Uninstall Monochrome apk first if it is already installed.
if _PREFIX_MONOCHROME in webview_apk:
util.ADBUninstallPackage(webview_package, args.device_id)
out = util.ADBInstallPackage(webview_apk, args.device_id)
if 'Success' in out:
print '%s installation succeeded.' % webview_apk
else:
print '%s installation failed.' % webview_apk
# It is Clank test then downloaded app is the test app.
elif args.platform == appium_driver_util.ANDROID:
args.app_path = gsutil_download.DownloadAndroidApp(
args.gsutil_download, args.channel, args.device_id, False)
else:
args.app_path = gsutil_download.DownloadIOSApp(
args.gsutil_download, args.channel)
if args.app_path:
_TEMPFILES.Add(args.app_path)
if args.webview:
api_level = device_info.GetAndroidAPILevel(args.device_id)
exists_package = util.CheckPackage(webview_package, args.device_id)
if api_level >= device_info.ANDROID_N_API_VERSION and exists_package:
cmd = [
'shell', 'cmd', 'webviewupdate', 'set-webview-implementation',
webview_package
]
util.RunADBProcess(cmd, args.device_id)
if args.package_pull:
args.app_path = gsutil_download.PullApp(args.package_pull, args.device_id)
_TEMPFILES.Add(args.app_path)
if not args.app_path:
args.app_path = os.path.abspath(args.channel +
_APP_EXTENSION[args.platform])
if not args.test_suite:
if args.csv:
spreadsheet_data = [el.strip() for el in args.csv.split(',')]
if len(spreadsheet_data) < 2:
raise franky_testsuite.ArgumentError(' '.join([
'--csv has to have at least 2 comma separated parameters:',
'"spreadsheet_key, workbook_id"']))
args.test_suite = download_testcases_csv.DownloadCSVFromGoogleSheet(
args, spreadsheet_data[0], set(spreadsheet_data[1:]))
for filename in args.test_suite:
_TEMPFILES.Add(filename)
else:
args.test_suite = ['*%s*.csv' % args.channel]
if not args.report_folder:
args.report_folder = os.path.split(args.test_suite[0])[0]
return args
def main(passed_args=None):
try:
franky_testsuite.ExecutTests(_ParseArgs(passed_args))
finally:
_TEMPFILES.DeleteAll()
if __name__ == '__main__':
main()