From 310e8282626e0caed98c6423c565cc7d879c4085 Mon Sep 17 00:00:00 2001 From: Jennifer Richards Date: Thu, 14 Apr 2022 15:35:07 -0300 Subject: [PATCH] fix: offset scrollspy so righthand-nav highlights the correct entry (#3820) Also rewrites scroll_to_element() using javascript. This seems to be less flaky than the ActionChains implementation. Slight change in behavior - now scrolls the requested element to the middle of the window instead of barely into view. --- ietf/meeting/tests_js.py | 7 +++---- ietf/static/js/ietf.js | 4 ++++ ietf/utils/jstest.py | 13 ++++++++++--- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/ietf/meeting/tests_js.py b/ietf/meeting/tests_js.py index e272ae24e..2b8394324 100644 --- a/ietf/meeting/tests_js.py +++ b/ietf/meeting/tests_js.py @@ -1529,10 +1529,8 @@ class AgendaTests(IetfSeleniumTestCase): ), 'Modal open button not found or not clickable', ) - # FIXME: no idea why we need js instead of the following: - # self.scroll_to_element(open_modal_button) - # open_modal_button.click() - self.driver.execute_script("arguments[0].click();", open_modal_button) + self.scroll_to_element(open_modal_button) + open_modal_button.click() WebDriverWait(self.driver, 2).until( expected_conditions.visibility_of(modal_div), 'Modal did not become visible after clicking open button', @@ -1586,6 +1584,7 @@ class AgendaTests(IetfSeleniumTestCase): ) self.scroll_to_element(open_modal_button) open_modal_button.click() + # self.driver.execute_script("arguments[0].click();", open_modal_button) WebDriverWait(self.driver, 2).until( expected_conditions.visibility_of(modal_div), 'Modal did not become visible after clicking open button for refresh test', diff --git a/ietf/static/js/ietf.js b/ietf/static/js/ietf.js index 6e9d33f67..c34a63b08 100644 --- a/ietf/static/js/ietf.js +++ b/ietf/static/js/ietf.js @@ -251,9 +251,13 @@ $(function () { } }); + // offset the scrollspy to account for the menu bar + const contentOffset = contentElement ? contentElement.offset().top : 0; + $("body") .attr("data-bs-spy", "scroll") .attr("data-bs-target", "#righthand-nav") + .attr("data-bs-offset", contentOffset) .scrollspy("refresh"); } diff --git a/ietf/utils/jstest.py b/ietf/utils/jstest.py index a35172a01..722b40581 100644 --- a/ietf/utils/jstest.py +++ b/ietf/utils/jstest.py @@ -11,7 +11,6 @@ try: from selenium import webdriver from selenium.webdriver.chrome.service import Service from selenium.webdriver.chrome.options import Options - from selenium.webdriver.common.action_chains import ActionChains from selenium.webdriver.common.by import By from selenium.webdriver.common.desired_capabilities import DesiredCapabilities except ImportError as e: @@ -86,8 +85,16 @@ class IetfSeleniumTestCase(IetfLiveServerTestCase): def scroll_to_element(self, element): """Scroll an element into view""" - actions = ActionChains(self.driver) - actions.move_to_element(element).perform() + # Compute the offset to put the element in the center of the window + win_height = self.driver.get_window_rect()['height'] + offset = element.rect['y'] + (element.rect['height'] - win_height) // 2 + self.driver.execute_script( + 'window.scroll({top: arguments[0], behavior: "instant"})', + offset, + ) + # The ActionChains approach below seems to be fragile, hence he JS above. + # actions = ActionChains(self.driver) + # actions.move_to_element(element).perform() class presence_of_element_child_by_css_selector: