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}')
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:
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)