|
2 | 2 | import os |
3 | 3 |
|
4 | 4 | from selenium import webdriver |
| 5 | +from selenium.webdriver.chrome.options import Options as ChromeOptions |
| 6 | +from selenium.webdriver.edge.options import Options as EdgeOptions |
| 7 | +from selenium.webdriver.firefox.options import Options as FirefoxOptions |
5 | 8 |
|
6 | 9 | import settings |
7 | 10 |
|
8 | 11 |
|
9 | 12 | def launch_driver(driver_name=settings.DRIVER, desired_capabilities=None): |
10 | | - """Create and configure a WebDriver. |
11 | | - Args: |
12 | | - driver_name : Name of WebDriver to use |
13 | | - desired_capabilities : Desired browser specs |
14 | | - """ |
15 | | - driver = None |
| 13 | + """Create and configure a WebDriver for local or remote (BrowserStack) runs.""" |
16 | 14 |
|
17 | | - try: |
18 | | - driver_cls = getattr(webdriver, driver_name) |
19 | | - except AttributeError: |
20 | | - driver_cls = getattr(webdriver, settings.DRIVER) |
| 15 | + driver = None |
21 | 16 |
|
22 | 17 | if driver_name == 'Remote': |
23 | | - |
| 18 | + # Set BrowserStack capabilities |
24 | 19 | if desired_capabilities is None: |
25 | 20 | desired_capabilities = settings.DESIRED_CAP |
26 | 21 | command_executor = 'http://{}:{}@hub.browserstack.com:80/wd/hub'.format( |
27 | 22 | settings.BSTACK_USER, settings.BSTACK_KEY |
28 | 23 | ) |
29 | 24 |
|
30 | | - if settings.BUILD == 'firefox': |
31 | | - # Create a temporary Firefox WebDriver to fetch the current user agent |
32 | | - temp_options = webdriver.FirefoxOptions() |
33 | | - temp_driver = webdriver.Firefox(options=temp_options) |
34 | | - default_user_agent = temp_driver.execute_script( |
35 | | - 'return navigator.userAgent;' |
36 | | - ) |
37 | | - temp_driver.quit() |
38 | | - |
39 | | - # Append "Selenium Bot" to the existing user agent |
40 | | - custom_user_agent = f'{default_user_agent} OSF Selenium Bot' |
41 | | - |
42 | | - from selenium.webdriver.firefox.options import Options |
43 | | - |
44 | | - ffo = Options() |
| 25 | + browser = settings.BUILD.lower() |
45 | 26 |
|
46 | | - # Set custom user agent |
47 | | - ffo.set_preference('general.useragent.override', custom_user_agent) |
48 | | - |
49 | | - # Set the default download location [0=Desktop, 1=Downloads, 2=Specified location] |
50 | | - ffo.set_preference('browser.download.folderList', 1) |
51 | | - |
52 | | - # Disable the OS-level pop-up modal |
53 | | - ffo.set_preference('browser.download.manager.showWhenStarting', False) |
54 | | - ffo.set_preference('browser.helperApps.alwaysAsk.force', False) |
55 | | - ffo.set_preference('browser.download.manager.alertOnEXEOpen', False) |
56 | | - ffo.set_preference('browser.download.manager.closeWhenDone', True) |
57 | | - ffo.set_preference('browser.download.manager.showAlertOnComplete', False) |
58 | | - ffo.set_preference('browser.download.manager.useWindow', False) |
59 | | - # Specify the file types supported by the download |
60 | | - ffo.set_preference( |
61 | | - 'browser.helperApps.neverAsk.saveToDisk', |
62 | | - 'text/plain, application/octet-stream, application/binary, text/csv, application/csv, ' |
63 | | - 'application/excel, text/comma-separated-values, text/xml, application/xml, binary/octet-stream', |
64 | | - ) |
65 | | - # Block Third Party Tracking Cookies (Default in Firefox is now 5 which blocks |
66 | | - # all Cross-site cookies) |
67 | | - ffo.set_preference('network.cookie.cookieBehavior', 4) |
68 | | - driver = driver_cls( |
| 27 | + if browser == 'firefox': |
| 28 | + ffo = FirefoxOptions() |
| 29 | + # Set custom user agent via capabilities (not by launching a local browser) |
| 30 | + desired_capabilities['browserName'] = 'Firefox' |
| 31 | + desired_capabilities['os'] = 'Windows' |
| 32 | + desired_capabilities['osVersion'] = '11' |
| 33 | + desired_capabilities['moz:firefoxOptions'] = { |
| 34 | + 'prefs': {'general.useragent.override': 'OSF Selenium Bot'} |
| 35 | + } |
| 36 | + driver = webdriver.Remote( |
69 | 37 | command_executor=command_executor, |
70 | 38 | desired_capabilities=desired_capabilities, |
71 | 39 | options=ffo, |
72 | 40 | ) |
73 | | - elif settings.BUILD == 'chrome': |
74 | | - from selenium.webdriver.chrome.options import Options |
75 | 41 |
|
76 | | - chrome_options: Options = Options() |
| 42 | + elif browser == 'chrome': |
| 43 | + chrome_options = ChromeOptions() |
77 | 44 | chrome_options.add_argument('--disable-gpu') |
78 | 45 | chrome_options.add_argument('window-size=1200x600') |
79 | | - |
80 | | - # Fetch default user agent |
81 | | - temp_driver = driver_cls( |
| 46 | + chrome_options.add_argument(f'user-agent={"OSF Selenium Bot"}') |
| 47 | + desired_capabilities['browserName'] = 'Chrome' |
| 48 | + desired_capabilities['os'] = 'Windows' |
| 49 | + desired_capabilities['osVersion'] = '11' |
| 50 | + desired_capabilities['goog:chromeOptions'] = { |
| 51 | + 'args': chrome_options.arguments |
| 52 | + } |
| 53 | + driver = webdriver.Remote( |
82 | 54 | command_executor=command_executor, |
83 | 55 | desired_capabilities=desired_capabilities, |
84 | 56 | options=chrome_options, |
85 | 57 | ) |
86 | | - default_user_agent = temp_driver.execute_script( |
87 | | - 'return navigator.userAgent;' |
88 | | - ) |
89 | | - temp_driver.quit() |
90 | | - |
91 | | - # Append "OSF Selenium Bot" to the existing user agent |
92 | | - custom_user_agent = f'{default_user_agent} OSF Selenium Bot' |
93 | | - chrome_options.add_argument(f'user-agent={custom_user_agent}') |
94 | | - |
95 | | - # Make a copy of desired capabilities for Chrome |
96 | | - desired_capabilities = settings.DESIRED_CAP.copy() |
97 | | - |
98 | | - # Attach Chrome options |
99 | | - desired_capabilities['goog:chromeOptions'] = { |
100 | | - 'args': chrome_options.arguments |
101 | | - } |
102 | 58 |
|
103 | | - driver = driver_cls( |
| 59 | + elif browser == 'edge': |
| 60 | + edge_options = EdgeOptions() |
| 61 | + desired_capabilities['browserName'] = 'Edge' |
| 62 | + desired_capabilities['os'] = 'Windows' |
| 63 | + desired_capabilities['osVersion'] = '11' |
| 64 | + driver = webdriver.Remote( |
104 | 65 | command_executor=command_executor, |
105 | 66 | desired_capabilities=desired_capabilities, |
106 | | - options=chrome_options, |
| 67 | + options=edge_options, |
107 | 68 | ) |
108 | | - elif settings.BUILD == 'edge': |
109 | | - # Use default settings for edge driver |
110 | | - # We can update this once we upgrade to selenium v4 |
111 | | - driver = webdriver.Edge() |
112 | 69 |
|
113 | | - elif driver_name == 'Chrome' and settings.HEADLESS: |
114 | | - from selenium.webdriver.chrome.options import Options |
| 70 | + else: |
| 71 | + raise ValueError(f'Unsupported browser: {browser}') |
115 | 72 |
|
116 | | - chrome_options = Options() |
| 73 | + # Local browser launches below (for local development) |
| 74 | + elif driver_name == 'Chrome' and settings.HEADLESS: |
| 75 | + chrome_options = ChromeOptions() |
117 | 76 | chrome_options.add_argument('--headless') |
118 | 77 | chrome_options.add_argument('--disable-gpu') |
119 | 78 | chrome_options.add_argument('window-size=1200x600') |
120 | | - driver = driver_cls(options=chrome_options) |
121 | | - elif driver_name == 'Chrome' and not settings.HEADLESS: |
122 | | - from selenium.webdriver.chrome.options import Options |
| 79 | + driver = webdriver.Chrome(options=chrome_options) |
123 | 80 |
|
124 | | - chrome_options = Options() |
125 | | - # disable w3c for local testing |
126 | | - chrome_options.add_experimental_option('w3c', False) |
| 81 | + elif driver_name == 'Chrome' and not settings.HEADLESS: |
| 82 | + chrome_options = ChromeOptions() |
127 | 83 | preferences = {'download.default_directory': ''} |
128 | 84 | chrome_options.add_experimental_option('prefs', preferences) |
129 | | - driver = driver_cls(options=chrome_options) |
130 | | - elif driver_name == 'Firefox' and not settings.HEADLESS: |
131 | | - from selenium.webdriver.firefox.options import Options |
132 | | - |
133 | | - ffo = Options() |
134 | | - # Set the default download location [0=Desktop, 1=Downloads, 2=Specified location] |
135 | | - ffo.set_preference('browser.download.folderList', 1) |
136 | | - ffo.set_preference('browser.download.manager.showWhenStarting', False) |
137 | | - ffo.set_preference('browser.helperApps.alwaysAsk.force', False) |
138 | | - ffo.set_preference( |
139 | | - 'browser.helperApps.neverAsk.saveToDisk', |
140 | | - 'text/plain, application/octet-stream, application/binary, text/csv, application/csv, ' |
141 | | - 'application/excel, text/comma-separated-values, text/xml, application/xml, binary/octet-stream', |
142 | | - ) |
143 | | - # Block Third Party Tracking Cookies (Default in Firefox is now 5 which blocks |
144 | | - # all Cross-site cookies) |
145 | | - ffo.set_preference('network.cookie.cookieBehavior', 4) |
146 | | - # Force Firefox to open links in new tab instead of new browser window. |
147 | | - ffo.set_preference('browser.link.open_newwindow', 3) |
148 | | - driver = driver_cls(options=ffo) |
149 | | - elif driver_name == 'Edge' and not settings.HEADLESS: |
150 | | - driver = webdriver.Edge() |
| 85 | + driver = webdriver.Chrome(options=chrome_options) |
| 86 | + |
| 87 | + elif driver_name == 'Firefox': |
| 88 | + ffo = FirefoxOptions() |
| 89 | + ffo.binary_location = r'C:\Program Files\Mozilla Firefox\firefox.exe' |
| 90 | + driver = webdriver.Firefox(options=ffo) |
151 | 91 |
|
| 92 | + elif driver_name == 'Edge': |
| 93 | + edge_options = EdgeOptions() |
| 94 | + driver = webdriver.Edge(options=edge_options) |
152 | 95 | else: |
153 | | - driver = driver_cls() |
| 96 | + driver = getattr(webdriver, driver_name)() |
154 | 97 |
|
155 | 98 | if driver is None: |
156 | 99 | raise RuntimeError( |
|
0 commit comments