diff options
Diffstat (limited to 'bitbake/lib/toaster/tests/browser/selenium_helpers_base.py')
-rw-r--r-- | bitbake/lib/toaster/tests/browser/selenium_helpers_base.py | 76 |
1 files changed, 65 insertions, 11 deletions
diff --git a/bitbake/lib/toaster/tests/browser/selenium_helpers_base.py b/bitbake/lib/toaster/tests/browser/selenium_helpers_base.py index 644d45fe58..393be75496 100644 --- a/bitbake/lib/toaster/tests/browser/selenium_helpers_base.py +++ b/bitbake/lib/toaster/tests/browser/selenium_helpers_base.py | |||
@@ -19,11 +19,15 @@ import os | |||
19 | import time | 19 | import time |
20 | import unittest | 20 | import unittest |
21 | 21 | ||
22 | import pytest | ||
22 | from selenium import webdriver | 23 | from selenium import webdriver |
24 | from selenium.webdriver.support import expected_conditions as EC | ||
23 | from selenium.webdriver.support.ui import WebDriverWait | 25 | from selenium.webdriver.support.ui import WebDriverWait |
26 | from selenium.webdriver.common.by import By | ||
24 | from selenium.webdriver.common.desired_capabilities import DesiredCapabilities | 27 | from selenium.webdriver.common.desired_capabilities import DesiredCapabilities |
25 | from selenium.common.exceptions import NoSuchElementException, \ | 28 | from selenium.common.exceptions import NoSuchElementException, \ |
26 | StaleElementReferenceException, TimeoutException | 29 | StaleElementReferenceException, TimeoutException, \ |
30 | SessionNotCreatedException | ||
27 | 31 | ||
28 | def create_selenium_driver(cls,browser='chrome'): | 32 | def create_selenium_driver(cls,browser='chrome'): |
29 | # set default browser string based on env (if available) | 33 | # set default browser string based on env (if available) |
@@ -32,9 +36,32 @@ def create_selenium_driver(cls,browser='chrome'): | |||
32 | browser = env_browser | 36 | browser = env_browser |
33 | 37 | ||
34 | if browser == 'chrome': | 38 | if browser == 'chrome': |
35 | return webdriver.Chrome( | 39 | options = webdriver.ChromeOptions() |
36 | service_args=["--verbose", "--log-path=selenium.log"] | 40 | options.add_argument('--headless') |
37 | ) | 41 | options.add_argument('--disable-infobars') |
42 | options.add_argument('--disable-dev-shm-usage') | ||
43 | options.add_argument('--no-sandbox') | ||
44 | options.add_argument('--remote-debugging-port=9222') | ||
45 | try: | ||
46 | return webdriver.Chrome(options=options) | ||
47 | except SessionNotCreatedException as e: | ||
48 | exit_message = "Halting tests prematurely to avoid cascading errors." | ||
49 | # check if chrome / chromedriver exists | ||
50 | chrome_path = os.popen("find ~/.cache/selenium/chrome/ -name 'chrome' -type f -print -quit").read().strip() | ||
51 | if not chrome_path: | ||
52 | pytest.exit(f"Failed to install/find chrome.\n{exit_message}") | ||
53 | chromedriver_path = os.popen("find ~/.cache/selenium/chromedriver/ -name 'chromedriver' -type f -print -quit").read().strip() | ||
54 | if not chromedriver_path: | ||
55 | pytest.exit(f"Failed to install/find chromedriver.\n{exit_message}") | ||
56 | # check if depends on each are fulfilled | ||
57 | depends_chrome = os.popen(f"ldd {chrome_path} | grep 'not found'").read().strip() | ||
58 | if depends_chrome: | ||
59 | pytest.exit(f"Missing chrome dependencies.\n{depends_chrome}\n{exit_message}") | ||
60 | depends_chromedriver = os.popen(f"ldd {chromedriver_path} | grep 'not found'").read().strip() | ||
61 | if depends_chromedriver: | ||
62 | pytest.exit(f"Missing chromedriver dependencies.\n{depends_chromedriver}\n{exit_message}") | ||
63 | # print original error otherwise | ||
64 | pytest.exit(f"Failed to start chromedriver.\n{e}\n{exit_message}") | ||
38 | elif browser == 'firefox': | 65 | elif browser == 'firefox': |
39 | return webdriver.Firefox() | 66 | return webdriver.Firefox() |
40 | elif browser == 'marionette': | 67 | elif browser == 'marionette': |
@@ -66,7 +93,9 @@ class Wait(WebDriverWait): | |||
66 | _TIMEOUT = 10 | 93 | _TIMEOUT = 10 |
67 | _POLL_FREQUENCY = 0.5 | 94 | _POLL_FREQUENCY = 0.5 |
68 | 95 | ||
69 | def __init__(self, driver): | 96 | def __init__(self, driver, timeout=_TIMEOUT, poll=_POLL_FREQUENCY): |
97 | self._TIMEOUT = timeout | ||
98 | self._POLL_FREQUENCY = poll | ||
70 | super(Wait, self).__init__(driver, self._TIMEOUT, self._POLL_FREQUENCY) | 99 | super(Wait, self).__init__(driver, self._TIMEOUT, self._POLL_FREQUENCY) |
71 | 100 | ||
72 | def until(self, method, message=''): | 101 | def until(self, method, message=''): |
@@ -138,6 +167,8 @@ class SeleniumTestCaseBase(unittest.TestCase): | |||
138 | """ Clean up webdriver driver """ | 167 | """ Clean up webdriver driver """ |
139 | 168 | ||
140 | cls.driver.quit() | 169 | cls.driver.quit() |
170 | # Allow driver resources to be properly freed before proceeding with further tests | ||
171 | time.sleep(5) | ||
141 | super(SeleniumTestCaseBase, cls).tearDownClass() | 172 | super(SeleniumTestCaseBase, cls).tearDownClass() |
142 | 173 | ||
143 | def get(self, url): | 174 | def get(self, url): |
@@ -151,13 +182,20 @@ class SeleniumTestCaseBase(unittest.TestCase): | |||
151 | abs_url = '%s%s' % (self.live_server_url, url) | 182 | abs_url = '%s%s' % (self.live_server_url, url) |
152 | self.driver.get(abs_url) | 183 | self.driver.get(abs_url) |
153 | 184 | ||
185 | try: # Ensure page is loaded before proceeding | ||
186 | self.wait_until_visible("#global-nav", poll=3) | ||
187 | except NoSuchElementException: | ||
188 | self.driver.implicitly_wait(3) | ||
189 | except TimeoutException: | ||
190 | self.driver.implicitly_wait(3) | ||
191 | |||
154 | def find(self, selector): | 192 | def find(self, selector): |
155 | """ Find single element by CSS selector """ | 193 | """ Find single element by CSS selector """ |
156 | return self.driver.find_element_by_css_selector(selector) | 194 | return self.driver.find_element(By.CSS_SELECTOR, selector) |
157 | 195 | ||
158 | def find_all(self, selector): | 196 | def find_all(self, selector): |
159 | """ Find all elements matching CSS selector """ | 197 | """ Find all elements matching CSS selector """ |
160 | return self.driver.find_elements_by_css_selector(selector) | 198 | return self.driver.find_elements(By.CSS_SELECTOR, selector) |
161 | 199 | ||
162 | def element_exists(self, selector): | 200 | def element_exists(self, selector): |
163 | """ | 201 | """ |
@@ -170,18 +208,34 @@ class SeleniumTestCaseBase(unittest.TestCase): | |||
170 | """ Return the element which currently has focus on the page """ | 208 | """ Return the element which currently has focus on the page """ |
171 | return self.driver.switch_to.active_element | 209 | return self.driver.switch_to.active_element |
172 | 210 | ||
173 | def wait_until_present(self, selector): | 211 | def wait_until_present(self, selector, poll=0.5): |
174 | """ Wait until element matching CSS selector is on the page """ | 212 | """ Wait until element matching CSS selector is on the page """ |
175 | is_present = lambda driver: self.find(selector) | 213 | is_present = lambda driver: self.find(selector) |
176 | msg = 'An element matching "%s" should be on the page' % selector | 214 | msg = 'An element matching "%s" should be on the page' % selector |
177 | element = Wait(self.driver).until(is_present, msg) | 215 | element = Wait(self.driver, poll=poll).until(is_present, msg) |
216 | if poll > 2: | ||
217 | time.sleep(poll) # element need more delay to be present | ||
178 | return element | 218 | return element |
179 | 219 | ||
180 | def wait_until_visible(self, selector): | 220 | def wait_until_visible(self, selector, poll=1): |
181 | """ Wait until element matching CSS selector is visible on the page """ | 221 | """ Wait until element matching CSS selector is visible on the page """ |
182 | is_visible = lambda driver: self.find(selector).is_displayed() | 222 | is_visible = lambda driver: self.find(selector).is_displayed() |
183 | msg = 'An element matching "%s" should be visible' % selector | 223 | msg = 'An element matching "%s" should be visible' % selector |
184 | Wait(self.driver).until(is_visible, msg) | 224 | Wait(self.driver, poll=poll).until(is_visible, msg) |
225 | time.sleep(poll) # wait for visibility to settle | ||
226 | return self.find(selector) | ||
227 | |||
228 | def wait_until_clickable(self, selector, poll=1): | ||
229 | """ Wait until element matching CSS selector is visible on the page """ | ||
230 | WebDriverWait( | ||
231 | self.driver, | ||
232 | Wait._TIMEOUT, | ||
233 | poll_frequency=poll | ||
234 | ).until( | ||
235 | EC.element_to_be_clickable((By.ID, selector.removeprefix('#') | ||
236 | ) | ||
237 | ) | ||
238 | ) | ||
185 | return self.find(selector) | 239 | return self.find(selector) |
186 | 240 | ||
187 | def wait_until_focused(self, selector): | 241 | def wait_until_focused(self, selector): |