def CreateParser(self, *args, **kwargs): parser = optparse.OptionParser(*args, **kwargs) # Options to interact with a potential external results processor. parser.set_defaults( external_results_processor=False, intermediate_dir=None, # TODO(crbug.com/928275): Remove these when Telemetry is no longer # involved in any results processing. output_dir=None, output_formats=[], legacy_output_formats=[], reset_results=True, results_label='telemetry_run', upload_results=False, upload_bucket=None) # Selection group group = optparse.OptionGroup(parser, 'Which browser to use') group.add_option('--browser', dest='browser_type', default=None, help='Browser type to run, ' 'in order of priority. Supported values: list,%s' % ', '.join(browser_finder.FindAllBrowserTypes())) group.add_option('--browser-executable', dest='browser_executable', help='The exact browser to run.') group.add_option('--chrome-root', dest='chrome_root', help='Where to look for chrome builds. ' 'Defaults to searching parent dirs by default.') group.add_option( '--chromium-output-directory', dest='chromium_output_dir', help='Where to look for build artifacts. ' 'Can also be specified by setting environment variable ' 'CHROMIUM_OUTPUT_DIR.') group.add_option( '--remote', dest='cros_remote', help='The hostname of a remote ChromeOS device to use.') group.add_option( '--remote-ssh-port', type=int, default=socket.getservbyname('ssh'), dest='cros_remote_ssh_port', help= 'The SSH port of the remote ChromeOS device (requires --remote).') compat_mode_options_list = [ compat_mode_options.NO_FIELD_TRIALS, compat_mode_options.IGNORE_CERTIFICATE_ERROR, compat_mode_options.LEGACY_COMMAND_LINE_PATH, compat_mode_options.GPU_BENCHMARKING_FALLBACKS, compat_mode_options.DONT_REQUIRE_ROOTED_DEVICE ] parser.add_option( '--compatibility-mode', action='append', dest='compatibility_mode', choices=compat_mode_options_list, default=[], help='Select the compatibility change that you want to enforce when ' 'running benchmarks. The options are: %s' % ', '.join(compat_mode_options_list)) parser.add_option( '--experimental-proto-trace-format', action='store_true', help='Request traces from Chrome in protobuf file format.') identity = None testing_rsa = os.path.join(util.GetTelemetryThirdPartyDir(), 'chromite', 'ssh_keys', 'testing_rsa') if os.path.exists(testing_rsa): identity = testing_rsa group.add_option( '--identity', dest='cros_ssh_identity', default=identity, help= 'The identity file to use when ssh\'ing into the ChromeOS device') parser.add_option_group(group) # Debugging options group = optparse.OptionGroup(parser, 'When things go wrong') group.add_option('--print-bootstrap-deps', action='store_true', help='Output bootstrap deps list.') group.add_option( '--extra-chrome-categories', dest='extra_chrome_categories', type=str, help= 'Filter string to enable additional chrome tracing categories. See' ' documentation here: https://cs.chromium.org/chromium/src/base/' 'trace_event/trace_config.h?rcl=' 'c8db6c6371ca047c24d41f3972d5819bc83d83ae&l=125') group.add_option( '--extra-atrace-categories', dest='extra_atrace_categories', type=str, help='Comma-separated list of extra atrace categories. Use atrace' ' --list_categories to get full list.') group.add_option( '--enable-systrace', dest='enable_systrace', action='store_true', help='Enable collection of systrace. (Useful on ChromeOS where' ' atrace is not supported; collects scheduling information.)') parser.add_option_group(group) # Platform options group = optparse.OptionGroup(parser, 'Platform options') group.add_option( '--no-performance-mode', action='store_true', help='Some platforms run on "full performance mode" where the ' 'test is executed at maximum CPU speed in order to minimize noise ' '(specially important for dashboards / continuous builds). ' 'This option prevents Telemetry from tweaking such platform settings.' ) # TODO(crbug.com/1025207): Rename this to --support-apk group.add_option( '--webview-embedder-apk', action="append", default=[], help= 'When running tests on android webview, more than one apk needs to' ' be installed. The apk running the test is said to embed webview. More' ' than one apk may be specified if needed.') parser.add_option_group(group) # Remote platform options group = optparse.OptionGroup(parser, 'Remote platform options') group.add_option('--android-blacklist-file', help='Device blacklist JSON file.') group.add_option( '--device', help='The device ID to use. ' 'If not specified, only 0 or 1 connected devices are supported. ' 'If specified as "android", all available Android devices are ' 'used.') group.add_option( '--install-bundle-module', dest='modules_to_install', action='append', default=[], help= 'Specify Android App Bundle modules to install in addition to the ' 'base module. Ignored on Non-Android platforms.') parser.add_option_group(group) group = optparse.OptionGroup(parser, 'Fuchsia platform options') group.add_option( '--fuchsia-output-dir', default='out/Release', help='Specify the build directory for the Fuchsia OS installed on ' 'the device.') parser.add_option_group(group) # CPU profiling on Android/Linux/ChromeOS. group = optparse.OptionGroup( parser, ('CPU profiling over intervals of interest, ' 'Android, Linux, and ChromeOS only')) group.add_option( '--interval-profiling-target', dest='interval_profiling_target', default='renderer:main', metavar='PROCESS_NAME[:THREAD_NAME]|"system_wide"', help= 'Run the CPU profiler on this process/thread (default=%default), ' 'which is supported only on Linux and Android, or system-wide, which ' 'is supported only on ChromeOS.') group.add_option( '--interval-profiling-period', dest='interval_profiling_periods', type='choice', choices=('navigation', 'interactions', 'story_run'), action='append', default=[], metavar='PERIOD', help='Run the CPU profiler during this test period. ' 'May be specified multiple times except when the story_run period is ' 'used; available choices are ["navigation", "interactions", ' '"story_run"]. Profile data will be written to ' 'artifacts/*.perf.data (Android/ChromeOS) or ' 'artifacts/*.profile.pb (Linux) files in the output directory. See ' 'https://developer.android.com/ndk/guides/simpleperf for more info on ' 'Android profiling via simpleperf.') group.add_option( '--interval-profiling-frequency', default=1000, metavar='FREQUENCY', type=int, help='Frequency of CPU profiling samples, in samples per second ' '(default=%default). This flag is used only on Android') group.add_option( '--interval-profiler-options', dest='interval_profiler_options', type=str, metavar='"--flag <options> ..."', help='Addtional arguments to pass to the CPU profiler. This is used ' 'only on ChromeOS. On ChromeOS, pass the linux perf\'s subcommand name ' 'followed by the options to pass to the perf tool. Supported perf ' 'subcommands are "record" and "stat". ' 'Eg: "record -e cycles -c 4000000 -g". Note: "-a" flag is added to the ' 'perf command by default. Do not pass options that are incompatible ' 'with the system-wide profile collection.') parser.add_option_group(group) # Browser options. self.browser_options.AddCommandLineArgs(parser) real_parse = parser.parse_args def ParseArgs(args=None): defaults = parser.get_default_values() for k, v in defaults.__dict__.items(): if k in self.__dict__ and self.__dict__[k] != None: continue self.__dict__[k] = v ret = real_parse(args, self) # pylint: disable=E1121 if self.chromium_output_dir: os.environ['CHROMIUM_OUTPUT_DIR'] = self.chromium_output_dir # Parse remote platform options. self.BuildRemotePlatformOptions() if self.remote_platform_options.device == 'list': if binary_manager.NeedsInit(): binary_manager.InitDependencyManager([]) devices = device_finder.GetDevicesMatchingOptions(self) print 'Available devices:' for device in devices: print ' ', device.name sys.exit(0) if self.browser_executable and not self.browser_type: self.browser_type = 'exact' if self.browser_type == 'list': if binary_manager.NeedsInit(): binary_manager.InitDependencyManager([]) devices = device_finder.GetDevicesMatchingOptions(self) if not devices: sys.exit(0) browser_types = {} for device in devices: try: possible_browsers = browser_finder.GetAllAvailableBrowsers( self, device) browser_types[device.name] = sorted([ browser.browser_type for browser in possible_browsers ]) except browser_finder_exceptions.BrowserFinderException as ex: print >> sys.stderr, 'ERROR: ', ex sys.exit(1) print 'Available browsers:' if len(browser_types) == 0: print ' No devices were found.' for device_name in sorted(browser_types.keys()): print ' ', device_name for browser_type in browser_types[device_name]: print ' ', browser_type if len(browser_types[device_name]) == 0: print ' No browsers found for this device' sys.exit(0) # Profiling other periods along with the story_run period leads to running # multiple profiling processes at the same time. The effects of performing # muliple CPU profiling at the same time is unclear and may generate # incorrect profiles so this will not be supported. if (len(self.interval_profiling_periods) > 1 and 'story_run' in self.interval_profiling_periods): print 'Cannot specify other periods along with the story_run period.' sys.exit(1) self.interval_profiler_options = shlex.split( self.interval_profiler_options) # Parse browser options. self.browser_options.UpdateFromParseResults(self) return ret parser.parse_args = ParseArgs return parser
def CreateParser(self, *args, **kwargs): parser = optparse.OptionParser(*args, **kwargs) # Selection group group = optparse.OptionGroup(parser, 'Which browser to use') group.add_option('--browser', dest='browser_type', default=None, help='Browser type to run, ' 'in order of priority. Supported values: list,%s' % ','.join(browser_finder.FindAllBrowserTypes(self))) group.add_option('--browser-executable', dest='browser_executable', help='The exact browser to run.') group.add_option('--chrome-root', dest='chrome_root', help='Where to look for chrome builds. ' 'Defaults to searching parent dirs by default.') group.add_option( '--chromium-output-directory', dest='chromium_output_dir', help='Where to look for build artifacts. ' 'Can also be specified by setting environment variable ' 'CHROMIUM_OUTPUT_DIR.') group.add_option( '--remote', dest='cros_remote', help='The hostname of a remote ChromeOS device to use.') group.add_option( '--remote-ssh-port', type=int, default=socket.getservbyname('ssh'), dest='cros_remote_ssh_port', help= 'The SSH port of the remote ChromeOS device (requires --remote).') parser.add_option( '--compatibility-mode', action='append', dest='compatibility_mode', choices=[ compact_mode_options.NO_FIELD_TRIALS, compact_mode_options.IGNORE_CERTIFICATE_ERROR, compact_mode_options.LEGACY_COMMAND_LINE_PATH, compact_mode_options.GPU_BENCHMARKING_FALLBACKS ], default=[], help='Select the compatibility change that you want to enforce when ' 'running benchmarks') identity = None testing_rsa = os.path.join(util.GetTelemetryThirdPartyDir(), 'chromite', 'ssh_keys', 'testing_rsa') if os.path.exists(testing_rsa): identity = testing_rsa group.add_option( '--identity', dest='cros_ssh_identity', default=identity, help= 'The identity file to use when ssh\'ing into the ChromeOS device') parser.add_option_group(group) # Debugging options group = optparse.OptionGroup(parser, 'When things go wrong') group.add_option('-v', '--verbose', action='count', dest='verbosity', help='Increase verbosity level (repeat as needed)') group.add_option('--print-bootstrap-deps', action='store_true', help='Output bootstrap deps list.') group.add_option( '--extra-chrome-categories', dest='extra_chrome_categories', type=str, help= 'Filter string to enable additional chrome tracing categories. See' ' documentation here: https://cs.chromium.org/chromium/src/base/' 'trace_event/trace_config.h?rcl=' 'c8db6c6371ca047c24d41f3972d5819bc83d83ae&l=125') group.add_option( '--extra-atrace-categories', dest='extra_atrace_categories', type=str, help='Comma-separated list of extra atrace categories. Use atrace' ' --list_categories to get full list.') group.add_option( '--enable-systrace', dest='enable_systrace', action='store_true', help='Enable collection of systrace. (Useful on ChromeOS where' ' atrace is not supported; collects scheduling information.)') parser.add_option_group(group) # Platform options group = optparse.OptionGroup(parser, 'Platform options') group.add_option( '--no-performance-mode', action='store_true', help='Some platforms run on "full performance mode" where the ' 'test is executed at maximum CPU speed in order to minimize noise ' '(specially important for dashboards / continuous builds). ' 'This option prevents Telemetry from tweaking such platform settings.' ) group.add_option( '--webview-embedder-apk', help= 'When running tests on android webview, more than one apk needs to' ' be installed. The apk running the test is said to embed webview.' ) parser.add_option_group(group) # Remote platform options group = optparse.OptionGroup(parser, 'Remote platform options') group.add_option('--android-blacklist-file', help='Device blacklist JSON file.') group.add_option( '--device', help='The device ID to use. ' 'If not specified, only 0 or 1 connected devices are supported. ' 'If specified as "android", all available Android devices are ' 'used.') parser.add_option_group(group) # CPU profiling on Android. group = optparse.OptionGroup( parser, ('CPU profiling over intervals of interest, ' 'Android and Linux only')) group.add_option( '--interval-profiling-target', dest='interval_profiling_target', default='renderer:main', metavar='PROCESS_NAME[:THREAD_NAME]', help= 'Run the CPU profiler on this process/thread (default=%default).') group.add_option( '--interval-profiling-period', dest='interval_profiling_periods', type='choice', choices=('navigation', 'interactions'), action='append', default=[], metavar='PERIOD', help='Run the CPU profiler during this test period. ' 'May be specified multiple times; available choices ' 'are ["navigation", "interactions"]. Profile data will be written to' 'artifacts/*.perf.data (Android) or artifacts/*.profile.pb (Linux) ' 'files in the output directory. See ' 'https://developer.android.com/ndk/guides/simpleperf for more info on ' 'Android profiling via simpleperf.') group.add_option( '--interval-profiling-frequency', default=1000, metavar='FREQUENCY', type=int, help='Frequency of CPU profiling samples, in samples per second ' '(default=%default).') parser.add_option_group(group) # Browser options. self.browser_options.AddCommandLineArgs(parser) real_parse = parser.parse_args def ParseArgs(args=None): defaults = parser.get_default_values() for k, v in defaults.__dict__.items(): if k in self.__dict__ and self.__dict__[k] != None: continue self.__dict__[k] = v ret = real_parse(args, self) # pylint: disable=E1121 if self.verbosity >= 2: global_hooks.InstallSpyOnPopenArgs() logging.getLogger().setLevel(logging.DEBUG) elif self.verbosity: logging.getLogger().setLevel(logging.INFO) else: logging.getLogger().setLevel(logging.WARNING) if self.chromium_output_dir: os.environ['CHROMIUM_OUTPUT_DIR'] = self.chromium_output_dir # Parse remote platform options. self.BuildRemotePlatformOptions() if self.remote_platform_options.device == 'list': if binary_manager.NeedsInit(): binary_manager.InitDependencyManager([]) devices = device_finder.GetDevicesMatchingOptions(self) print 'Available devices:' for device in devices: print ' ', device.name sys.exit(0) if self.browser_executable and not self.browser_type: self.browser_type = 'exact' if self.browser_type == 'list': if binary_manager.NeedsInit(): binary_manager.InitDependencyManager([]) devices = device_finder.GetDevicesMatchingOptions(self) if not devices: sys.exit(0) browser_types = {} for device in devices: try: possible_browsers = browser_finder.GetAllAvailableBrowsers( self, device) browser_types[device.name] = sorted([ browser.browser_type for browser in possible_browsers ]) except browser_finder_exceptions.BrowserFinderException as ex: print >> sys.stderr, 'ERROR: ', ex sys.exit(1) print 'Available browsers:' if len(browser_types) == 0: print ' No devices were found.' for device_name in sorted(browser_types.keys()): print ' ', device_name for browser_type in browser_types[device_name]: print ' ', browser_type if len(browser_types[device_name]) == 0: print ' No browsers found for this device' sys.exit(0) # Parse browser options. self.browser_options.UpdateFromParseResults(self) return ret parser.parse_args = ParseArgs return parser
def CreateParser(self, *args, **kwargs): parser = optparse.OptionParser(*args, **kwargs) # Selection group group = optparse.OptionGroup(parser, 'Which browser to use') group.add_option('--browser', dest='browser_type', default=None, help='Browser type to run, ' 'in order of priority. Supported values: list,%s' % ','.join(browser_finder.FindAllBrowserTypes(self))) group.add_option('--browser-executable', dest='browser_executable', help='The exact browser to run.') group.add_option('--chrome-root', dest='chrome_root', help='Where to look for chrome builds. ' 'Defaults to searching parent dirs by default.') group.add_option( '--chromium-output-directory', dest='chromium_output_dir', help='Where to look for build artifacts. ' 'Can also be specified by setting environment variable ' 'CHROMIUM_OUTPUT_DIR.') group.add_option( '--remote', dest='cros_remote', help='The hostname of a remote ChromeOS device to use.') group.add_option( '--remote-ssh-port', type=int, default=socket.getservbyname('ssh'), dest='cros_remote_ssh_port', help= 'The SSH port of the remote ChromeOS device (requires --remote).') identity = None testing_rsa = os.path.join(util.GetTelemetryThirdPartyDir(), 'chromite', 'ssh_keys', 'testing_rsa') if os.path.exists(testing_rsa): identity = testing_rsa group.add_option( '--identity', dest='cros_ssh_identity', default=identity, help= 'The identity file to use when ssh\'ing into the ChromeOS device') parser.add_option_group(group) # Debugging options group = optparse.OptionGroup(parser, 'When things go wrong') profiler_choices = profiler_finder.GetAllAvailableProfilers() group.add_option( '--profiler', default=None, type='choice', choices=profiler_choices, help='Record profiling data using this tool. Supported values: %s. ' '(Notice: this flag cannot be used for Timeline Based Measurement ' 'benchmarks.)' % ', '.join(profiler_choices)) group.add_option('-v', '--verbose', action='count', dest='verbosity', help='Increase verbosity level (repeat as needed)') group.add_option('--print-bootstrap-deps', action='store_true', help='Output bootstrap deps list.') parser.add_option_group(group) # Platform options group = optparse.OptionGroup(parser, 'Platform options') group.add_option( '--no-performance-mode', action='store_true', help='Some platforms run on "full performance mode" where the ' 'test is executed at maximum CPU speed in order to minimize noise ' '(specially important for dashboards / continuous builds). ' 'This option prevents Telemetry from tweaking such platform settings.' ) group.add_option( '--webview-embedder-apk', help= 'When running tests on android webview, more than one apk needs to' ' be installed. The apk running the test is said to embed webview.' ) parser.add_option_group(group) # Remote platform options group = optparse.OptionGroup(parser, 'Remote platform options') group.add_option('--android-blacklist-file', help='Device blacklist JSON file.') group.add_option( '--device', help='The device ID to use. ' 'If not specified, only 0 or 1 connected devices are supported. ' 'If specified as "android", all available Android devices are ' 'used.') parser.add_option_group(group) # Browser options. self.browser_options.AddCommandLineArgs(parser) real_parse = parser.parse_args def ParseArgs(args=None): defaults = parser.get_default_values() for k, v in defaults.__dict__.items(): if k in self.__dict__ and self.__dict__[k] != None: continue self.__dict__[k] = v ret = real_parse(args, self) # pylint: disable=E1121 if self.verbosity >= 2: logging.getLogger().setLevel(logging.DEBUG) elif self.verbosity: logging.getLogger().setLevel(logging.INFO) else: logging.getLogger().setLevel(logging.WARNING) if self.chromium_output_dir: os.environ['CHROMIUM_OUTPUT_DIR'] = self.chromium_output_dir # Parse remote platform options. self.BuildRemotePlatformOptions() if self.remote_platform_options.device == 'list': if binary_manager.NeedsInit(): binary_manager.InitDependencyManager([]) devices = device_finder.GetDevicesMatchingOptions(self) print 'Available devices:' for device in devices: print ' ', device.name sys.exit(0) if self.browser_executable and not self.browser_type: self.browser_type = 'exact' if self.browser_type == 'list': if binary_manager.NeedsInit(): binary_manager.InitDependencyManager([]) devices = device_finder.GetDevicesMatchingOptions(self) if not devices: sys.exit(0) browser_types = {} for device in devices: try: possible_browsers = browser_finder.GetAllAvailableBrowsers( self, device) browser_types[device.name] = sorted([ browser.browser_type for browser in possible_browsers ]) except browser_finder_exceptions.BrowserFinderException as ex: print >> sys.stderr, 'ERROR: ', ex sys.exit(1) print 'Available browsers:' if len(browser_types) == 0: print ' No devices were found.' for device_name in sorted(browser_types.keys()): print ' ', device_name for browser_type in browser_types[device_name]: print ' ', browser_type sys.exit(0) # Parse browser options. self.browser_options.UpdateFromParseResults(self) return ret parser.parse_args = ParseArgs return parser
def CreateParser(self, *args, **kwargs): parser = optparse.OptionParser(*args, **kwargs) # Selection group group = optparse.OptionGroup(parser, 'Which browser to use') group.add_option('--browser', dest='browser_type', default=None, help='Browser type to run, ' 'in order of priority. Supported values: list,%s' % ','.join(browser_finder.FindAllBrowserTypes(self))) group.add_option('--browser-executable', dest='browser_executable', help='The exact browser to run.') group.add_option('--chrome-root', dest='chrome_root', help='Where to look for chrome builds.' 'Defaults to searching parent dirs by default.') group.add_option('--device', dest='device', help='The device ID to use.' 'If not specified, only 0 or 1 connected devices are supported. If' 'specified as "android", all available Android devices are used.') group.add_option('--target-arch', dest='target_arch', help='The target architecture of the browser. Options available are: ' 'x64, x86_64, arm, arm64 and mips. ' 'Defaults to the default architecture of the platform if omitted.') group.add_option( '--remote', dest='cros_remote', help='The hostname of a remote ChromeOS device to use.') group.add_option( '--remote-ssh-port', type=int, default=socket.getservbyname('ssh'), dest='cros_remote_ssh_port', help='The SSH port of the remote ChromeOS device (requires --remote).') identity = None testing_rsa = os.path.join( util.GetChromiumSrcDir(), 'third_party', 'chromite', 'ssh_keys', 'testing_rsa') if os.path.exists(testing_rsa): identity = testing_rsa group.add_option('--identity', dest='cros_ssh_identity', default=identity, help='The identity file to use when ssh\'ing into the ChromeOS device') parser.add_option_group(group) # Debugging options group = optparse.OptionGroup(parser, 'When things go wrong') profiler_choices = profiler_finder.GetAllAvailableProfilers() group.add_option( '--profiler', default=None, type='choice', choices=profiler_choices, help='Record profiling data using this tool. Supported values: ' + ', '.join(profiler_choices)) group.add_option( '-v', '--verbose', action='count', dest='verbosity', help='Increase verbosity level (repeat as needed)') group.add_option('--print-bootstrap-deps', action='store_true', help='Output bootstrap deps list.') parser.add_option_group(group) # Platform options group = optparse.OptionGroup(parser, 'Platform options') group.add_option('--no-performance-mode', action='store_true', help='Some platforms run on "full performance mode" where the ' 'test is executed at maximum CPU speed in order to minimize noise ' '(specially important for dashboards / continuous builds). ' 'This option prevents Telemetry from tweaking such platform settings.') group.add_option('--android-rndis', dest='android_rndis', default=False, action='store_true', help='Use RNDIS forwarding on Android.') group.add_option('--no-android-rndis', dest='android_rndis', action='store_false', help='Do not use RNDIS forwarding on Android.' ' [default]') parser.add_option_group(group) # Browser options. self.browser_options.AddCommandLineArgs(parser) real_parse = parser.parse_args def ParseArgs(args=None): defaults = parser.get_default_values() for k, v in defaults.__dict__.items(): if k in self.__dict__ and self.__dict__[k] != None: continue self.__dict__[k] = v ret = real_parse(args, self) # pylint: disable=E1121 if self.verbosity >= 2: logging.getLogger().setLevel(logging.DEBUG) elif self.verbosity: logging.getLogger().setLevel(logging.INFO) else: logging.getLogger().setLevel(logging.WARNING) logging.basicConfig( format='%(levelname)s:%(name)s:%(asctime)s:%(message)s') if self.device == 'list': devices = device_finder.GetDevicesMatchingOptions(self) print 'Available devices:' for device in devices: print ' ', device.name sys.exit(0) if self.browser_executable and not self.browser_type: self.browser_type = 'exact' if self.browser_type == 'list': devices = device_finder.GetDevicesMatchingOptions(self) if not devices: sys.exit(0) browser_types = {} for device in devices: try: possible_browsers = browser_finder.GetAllAvailableBrowsers(self, device) browser_types[device.name] = sorted( [browser.browser_type for browser in possible_browsers]) except browser_finder_exceptions.BrowserFinderException as ex: print >> sys.stderr, 'ERROR: ', ex sys.exit(1) print 'Available browsers:' if len(browser_types) == 0: print ' No devices were found.' for device_name in sorted(browser_types.keys()): print ' ', device_name for browser_type in browser_types[device_name]: print ' ', browser_type sys.exit(0) # Parse browser options. self.browser_options.UpdateFromParseResults(self) return ret parser.parse_args = ParseArgs return parser