910e62b5创建于 1月15日历史提交
# Copyright 2023 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import attr
import logging
import os
import shutil

from contextlib import contextmanager
from typing import Optional

from chrome.test.variations.drivers import DriverFactory
from chrome.test.variations.test_utils.helper import timeout
from selenium import webdriver
from selenium.common.exceptions import WebDriverException
from selenium.webdriver import ChromeOptions

_DRIVER_CREATION_TIMEOUT_SEC = 30

@attr.attrs()
class DesktopDriverFactory(DriverFactory):
  """Driver factory for desktop platforms."""
  channel: Optional[str] = attr.attrib()
  crash_dump_dir: Optional[str] = attr.attrib()

  @timeout(_DRIVER_CREATION_TIMEOUT_SEC)
  def _get_driver(self, options):
    return webdriver.Chrome(service=self.get_driver_service(), options=options)

  @contextmanager
  def create_driver(
    self,
    seed_file: Optional[str] = None,
    options: Optional[ChromeOptions] = None
    ) -> webdriver.Remote:
    os.environ['BREAKPAD_DUMP_LOCATION'] = self.crash_dump_dir

    options = options or self.default_options

    if seed_file:
      assert os.path.exists(seed_file)
      options.add_argument(f'variations-test-seed-path={seed_file}')
      options.add_argument(
        f'fake-variations-channel={self.channel}')
      # TODO(http://crbug.com/379869158) -- remove this once the new
      # seed loading mechanism is fixed.
      options.add_argument(
        '--force-fieldtrials=SeedFileTrial/Default')
    options.add_experimental_option('excludeSwitches',
                                    ['disable-background-networking'])
    driver = None
    try:
      logging.info('Launching Chrome w/ caps: %s',
                   options.to_capabilities())
      driver = self._get_driver(options)
      self.wait_for_window(driver)
      yield driver
    except WebDriverException as e:
      # Report this to be part of test result.
      if os.listdir(self.crash_dump_dir):
        logging.error('Chrome crashed and exited abnormally.\n%s', e)
      else:
        logging.error('Uncaught WebDriver exception thrown.\n%s', e)
      raise
    finally:
      if driver:
        driver.quit()
      shutil.rmtree(self.crash_dump_dir, ignore_errors=True)