browser_options.py revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)# found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import optparse
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import sys
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import shlex
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)import logging
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)import copy
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import browser_finder
112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import profile_types
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)from telemetry.core import wpr_modes
13b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)from telemetry.core.platform.profiler import profiler_finder
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BrowserOptions(optparse.Values):
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  """Options to be used for discovering and launching a browser."""
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def __init__(self, browser_type=None):
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    optparse.Values.__init__(self)
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.browser_type = browser_type
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.browser_executable = None
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.chrome_root = None
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.android_device = None
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.cros_ssh_identity = None
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2790dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    # When set to True, the browser will use the default profile.  Telemetry
2890dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    # will not provide an alternate profile directory.
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.dont_override_profile = False
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.profile_dir = None
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.extra_browser_args = []
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.extra_wpr_args = []
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.show_stdout = False
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.extensions_to_load = []
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.cros_remote = None
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.wpr_mode = wpr_modes.WPR_OFF
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.wpr_make_javascript_deterministic = True
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.browser_user_agent_type = None
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
42b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    self.profiler_tool = None
43b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    self.profiler_dir = None
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.trace_dir = None
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    self.verbosity = 0
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.page_filter = None
482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    self.page_filter_exclude = None
492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def Copy(self):
512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return copy.deepcopy(self)
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  def CreateParser(self, *args, **kwargs):
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parser = optparse.OptionParser(*args, **kwargs)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Selection group
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group = optparse.OptionGroup(parser, 'Which browser to use')
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group.add_option('--browser',
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dest='browser_type',
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        default=None,
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        help='Browser type to run, '
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             'in order of priority. Supported values: list,%s' %
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             browser_finder.ALL_BROWSER_TYPES)
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group.add_option('--browser-executable',
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dest='browser_executable',
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        help='The exact browser to run.')
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group.add_option('--chrome-root',
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dest='chrome_root',
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        help='Where to look for chrome builds.'
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             'Defaults to searching parent dirs by default.')
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group.add_option('--device',
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dest='android_device',
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        help='The android device ID to use'
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)             'If not specified, only 0 or 1 connected devcies are supported.')
752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    group.add_option('--keep_test_server_ports', action='store_true',
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        help='Indicates the test server ports must be '
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             'kept. When this is run via a sharder '
782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             'the test server ports should be kept and '
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             'should not be reset.')
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group.add_option(
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        '--remote',
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dest='cros_remote',
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        help='The IP address of a remote ChromeOS device to use.')
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group.add_option('--identity',
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dest='cros_ssh_identity',
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        default=None,
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        help='The identity file to use when ssh\'ing into the ChromeOS device')
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parser.add_option_group(group)
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Browser options
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group = optparse.OptionGroup(parser, 'Browser options')
9290dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)    profile_choices = profile_types.GetProfileTypes()
932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    group.add_option('--profile-type',
942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        dest='profile_type',
952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        type='choice',
962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        default='clean',
972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        choices=profile_choices,
982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        help=('The user profile to use. A clean profile is used by default. '
992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              'Supported values: ' + ', '.join(profile_choices)))
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group.add_option('--extra-browser-args',
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        dest='extra_browser_args_as_string',
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        help='Additional arguments to pass to the browser when it starts')
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    group.add_option('--extra-wpr-args',
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        dest='extra_wpr_args_as_string',
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        help=('Additional arguments to pass to Web Page Replay. '
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)              'See third_party/webpagereplay/replay.py for usage.'))
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group.add_option('--show-stdout',
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        action='store_true',
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        help='When possible, will display the stdout of the process')
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parser.add_option_group(group)
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Page set options
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group = optparse.OptionGroup(parser, 'Page set options')
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group.add_option('--page-repeat', dest='page_repeat', default=1,
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        help='Number of times to repeat each individual ' +
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        'page in the pageset before proceeding.')
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group.add_option('--pageset-repeat', dest='pageset_repeat', default=1,
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        help='Number of times to repeat the entire pageset ' +
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        'before finishing.')
1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    group.add_option('--pageset-shuffle', action='store_true',
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        dest='pageset_shuffle',
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        help='Shuffle the order of pages within a pageset.')
1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    group.add_option('--pageset-shuffle-order-file',
1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        dest='pageset_shuffle_order_file', default=None,
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        help='Filename of an output of a previously run test on the current ' +
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        'pageset. The tests will run in the same order again, overriding ' +
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        'what is specified by --page-repeat and --pageset-repeat.')
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parser.add_option_group(group)
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    group = optparse.OptionGroup(parser, 'Web Page Replay options')
1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    group.add_option('--allow-live-sites',
1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        dest='allow_live_sites', action='store_true',
1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        help='Run against live sites if the Web Page Replay archives don\'t '
134c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)             'exist. Without this flag, the test will just fail instead '
1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)             'of running against live sites.')
1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    parser.add_option_group(group)
1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    # Debugging options
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group = optparse.OptionGroup(parser, 'When things go wrong')
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    group.add_option(
141b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      '--profiler-tool', dest='profiler_tool', default=None, type='choice',
142b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      choices=profiler_finder.GetAllAvailableProfilers(),
143b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      help=('Record sampling profilers with this tool. Supported values: ' +
144b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            ', '.join(profiler_finder.GetAllAvailableProfilers())))
145b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    group.add_option(
146b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      '--profiler-dir', dest='profiler_dir', default=None,
147b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      help='Record sampling profiles and store them in this directory.')
148b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)    group.add_option(
1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      '--trace-dir', dest='trace_dir', default=None,
1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      help='Record traces and store them in this directory.')
1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    group.add_option(
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      '-v', '--verbose', action='count', dest='verbosity',
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      help='Increase verbosity level (repeat as needed)')
1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    group.add_option('--print-bootstrap-deps',
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     action='store_true',
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)                     help='Output bootstrap deps list.')
1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    parser.add_option_group(group)
1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    # Platform options
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    group = optparse.OptionGroup(parser, 'Platform options')
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    group.add_option('--no-performance-mode', action='store_true',
1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        help='Some platforms run on "full performance mode" where the '
163c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        'test is executed at maximum CPU speed in order to minimize noise '
1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        '(specially important for dashboards / continuous builds). '
1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        'This option prevents Telemetry from tweaking such platform settings.')
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parser.add_option_group(group)
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    real_parse = parser.parse_args
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    def ParseArgs(args=None):
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      defaults = parser.get_default_values()
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      for k, v in defaults.__dict__.items():
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        if k in self.__dict__ and self.__dict__[k] != None:
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          continue
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.__dict__[k] = v
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      ret = real_parse(args, self) # pylint: disable=E1121
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if self.verbosity >= 2:
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        logging.basicConfig(level=logging.DEBUG)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      elif self.verbosity:
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        logging.basicConfig(level=logging.INFO)
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      else:
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        logging.basicConfig(level=logging.WARNING)
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
184b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)      if ((self.profiler_tool and not self.profiler_dir) or
185b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)          (not self.profiler_tool and self.profiler_dir)):
186b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        sys.stderr.write(
187b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)            'Must use --profiler-tool and --profiler-dir together.\n')
188b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)        sys.exit(1)
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if self.browser_executable and not self.browser_type:
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.browser_type = 'exact'
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if not self.browser_executable and not self.browser_type:
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sys.stderr.write('Must provide --browser=<type>. ' +
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                         'Use --browser=list for valid options.\n')
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sys.exit(1)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if self.browser_type == 'list':
196c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        try:
197c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          types = browser_finder.GetAllAvailableBrowserTypes(self)
198c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        except browser_finder.BrowserFinderException, ex:
199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          sys.stderr.write('ERROR: ' + str(ex))
200c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)          sys.exit(1)
201c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sys.stdout.write('Available browsers:\n')
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        sys.stdout.write('  %s\n' % '\n  '.join(types))
203c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)        sys.exit(0)
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      if self.extra_browser_args_as_string: # pylint: disable=E1101
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        tmp = shlex.split(
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)          self.extra_browser_args_as_string) # pylint: disable=E1101
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        self.extra_browser_args.extend(tmp)
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        delattr(self, 'extra_browser_args_as_string')
2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if self.extra_wpr_args_as_string: # pylint: disable=E1101
2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        tmp = shlex.split(
2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)          self.extra_wpr_args_as_string) # pylint: disable=E1101
2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        self.extra_wpr_args.extend(tmp)
2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        delattr(self, 'extra_wpr_args_as_string')
2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      if self.profile_type == 'default':
2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        self.dont_override_profile = True
21690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles)      self.profile_dir = profile_types.GetProfileDir(self.profile_type)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      return ret
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    parser.parse_args = ParseArgs
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return parser
2202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  def AppendExtraBrowserArg(self, arg):
2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    if arg not in self.extra_browser_args:
2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      self.extra_browser_args.append(arg)
224