fix: Selenium tests via scroll_and_click (#8150)
* fix: selenium tests scroll_and_click * fix: reduce default timeout to 5 seconds * fix: also use scroll_and_click on test_upcoming_materials_modal * fix: remove conditional check on restoring scroll CSS * fix: restore conditional check on restoring scroll CSS * chore: code comments and adding jstest.py to coverage ignore
This commit is contained in:
parent
d530e9aaba
commit
de494790b6
|
@ -249,7 +249,9 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
|
|||
self.assertTrue(s1_element.is_displayed()) # should still be displayed
|
||||
self.assertIn('hidden-parent', s1_element.get_attribute('class'),
|
||||
'Session should be hidden when parent disabled')
|
||||
s1_element.click() # try to select
|
||||
|
||||
self.scroll_and_click((By.CSS_SELECTOR, '#session{}'.format(s1.pk)))
|
||||
|
||||
self.assertNotIn('selected', s1_element.get_attribute('class'),
|
||||
'Session should not be selectable when parent disabled')
|
||||
|
||||
|
@ -299,9 +301,9 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
|
|||
'Session s1 should have moved to second meeting day')
|
||||
|
||||
# swap timeslot column - put session in a differently-timed timeslot
|
||||
self.driver.find_element(By.CSS_SELECTOR,
|
||||
self.scroll_and_click((By.CSS_SELECTOR,
|
||||
'.day .swap-timeslot-col[data-timeslot-pk="{}"]'.format(slot1b.pk)
|
||||
).click() # open modal on the second timeslot for room1
|
||||
)) # open modal on the second timeslot for room1
|
||||
self.assertTrue(self.driver.find_element(By.CSS_SELECTOR, "#swap-timeslot-col-modal").is_displayed())
|
||||
self.driver.find_element(By.CSS_SELECTOR,
|
||||
'#swap-timeslot-col-modal input[name="target_timeslot"][value="{}"]'.format(slot4.pk)
|
||||
|
@ -1373,13 +1375,8 @@ class InterimTests(IetfSeleniumTestCase):
|
|||
self.assertFalse(modal_div.is_displayed())
|
||||
|
||||
# Click the 'materials' button
|
||||
open_modal_button = self.wait.until(
|
||||
expected_conditions.element_to_be_clickable(
|
||||
(By.CSS_SELECTOR, '[data-bs-target="#modal-%s"]' % slug)
|
||||
),
|
||||
'Modal open button not found or not clickable',
|
||||
)
|
||||
open_modal_button.click()
|
||||
open_modal_button_locator = (By.CSS_SELECTOR, '[data-bs-target="#modal-%s"]' % slug)
|
||||
self.scroll_and_click(open_modal_button_locator)
|
||||
self.wait.until(
|
||||
expected_conditions.visibility_of(modal_div),
|
||||
'Modal did not become visible after clicking open button',
|
||||
|
|
|
@ -598,6 +598,7 @@ TEST_CODE_COVERAGE_EXCLUDE_FILES = [
|
|||
"ietf/review/import_from_review_tool.py",
|
||||
"ietf/utils/patch.py",
|
||||
"ietf/utils/test_data.py",
|
||||
"ietf/utils/jstest.py",
|
||||
]
|
||||
|
||||
# These are code line regex patterns
|
||||
|
|
|
@ -12,6 +12,8 @@ try:
|
|||
from selenium import webdriver
|
||||
from selenium.webdriver.firefox.service import Service
|
||||
from selenium.webdriver.firefox.options import Options
|
||||
from selenium.webdriver.support.ui import WebDriverWait
|
||||
from selenium.webdriver.support import expected_conditions
|
||||
from selenium.webdriver.common.by import By
|
||||
except ImportError as e:
|
||||
skip_selenium = True
|
||||
|
@ -87,6 +89,48 @@ class IetfSeleniumTestCase(IetfLiveServerTestCase):
|
|||
# actions = ActionChains(self.driver)
|
||||
# actions.move_to_element(element).perform()
|
||||
|
||||
def scroll_and_click(self, element_locator, timeout_seconds=5):
|
||||
"""
|
||||
Selenium has restrictions around clicking elements outside the viewport, so
|
||||
this wrapper encapsulates the boilerplate of forcing scrolling and clicking.
|
||||
|
||||
:param element_locator: A two item tuple of a Selenium locator eg `(By.CSS_SELECTOR, '#something')`
|
||||
"""
|
||||
|
||||
# so that we can restore the state of the webpage after clicking
|
||||
original_html_scroll_behaviour_to_restore = self.driver.execute_script('return document.documentElement.style.scrollBehavior')
|
||||
original_html_overflow_to_restore = self.driver.execute_script('return document.documentElement.style.overflow')
|
||||
|
||||
original_body_scroll_behaviour_to_restore = self.driver.execute_script('return document.body.style.scrollBehavior')
|
||||
original_body_overflow_to_restore = self.driver.execute_script('return document.body.style.overflow')
|
||||
|
||||
self.driver.execute_script('document.documentElement.style.scrollBehavior = "auto"')
|
||||
self.driver.execute_script('document.documentElement.style.overflow = "auto"')
|
||||
|
||||
self.driver.execute_script('document.body.style.scrollBehavior = "auto"')
|
||||
self.driver.execute_script('document.body.style.overflow = "auto"')
|
||||
|
||||
element = self.driver.find_element(element_locator[0], element_locator[1])
|
||||
self.scroll_to_element(element)
|
||||
|
||||
# Note that Selenium itself seems to have multiple definitions of 'clickable'.
|
||||
# You might expect that the following wait for the 'element_to_be_clickable'
|
||||
# would confirm that the following .click() would succeed but it doesn't.
|
||||
# That's why the preceeding code attempts to force scrolling to bring the
|
||||
# element into the viewport to allow clicking.
|
||||
WebDriverWait(self.driver, timeout_seconds).until(expected_conditions.element_to_be_clickable(element_locator))
|
||||
|
||||
element.click()
|
||||
|
||||
if original_html_scroll_behaviour_to_restore:
|
||||
self.driver.execute_script(f'document.documentElement.style.scrollBehavior = "{original_html_scroll_behaviour_to_restore}"')
|
||||
if original_html_overflow_to_restore:
|
||||
self.driver.execute_script(f'document.documentElement.style.overflow = "{original_html_overflow_to_restore}"')
|
||||
|
||||
if original_body_scroll_behaviour_to_restore:
|
||||
self.driver.execute_script(f'document.body.style.scrollBehavior = "{original_body_scroll_behaviour_to_restore}"')
|
||||
if original_body_overflow_to_restore:
|
||||
self.driver.execute_script(f'document.body.style.overflow = "{original_body_overflow_to_restore}"')
|
||||
|
||||
class presence_of_element_child_by_css_selector:
|
||||
"""Wait for presence of a child of a WebElement matching a CSS selector
|
||||
|
|
Loading…
Reference in a new issue