diff --git a/wafer/schedule/tests/test_schedule_datetime_widget.py b/wafer/schedule/tests/test_schedule_datetime_widget.py index f313ee0a..4508c72c 100644 --- a/wafer/schedule/tests/test_schedule_datetime_widget.py +++ b/wafer/schedule/tests/test_schedule_datetime_widget.py @@ -17,7 +17,7 @@ from django.urls import reverse from wafer.pages.models import Page -from wafer.tests.utils import ChromeTestRunner, FirefoxTestRunner +from wafer.tests.utils import ChromeTestRunner, FirefoxTestRunner, SELENIUM_WAIT_TIME from wafer.schedule.models import Venue, Slot, ScheduleBlock from wafer.schedule.tests.test_views import make_pages, make_items @@ -51,7 +51,7 @@ def setUp(self): def check_clock_button(self): """Standard check for the clock button contents""" # Find the clock button - clock_button = WebDriverWait(self.driver, 10).until( + clock_button = WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( expected_conditions.presence_of_element_located((By.CLASS_NAME, 'clock-icon')) ) # Check that the list isn't visible before we click @@ -59,7 +59,7 @@ def check_clock_button(self): style = clock_box.get_attribute('style') self.assertIn('display: none', style) clock_button.click() - timelist = WebDriverWait(self.driver, 10).until( + timelist = WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( expected_conditions.presence_of_element_located((By.CLASS_NAME, 'timelist')) ) clock_box = self.driver.find_element(By.ID, 'clockbox0') diff --git a/wafer/schedule/tests/test_schedule_editor.py b/wafer/schedule/tests/test_schedule_editor.py index 556f2440..524723ba 100644 --- a/wafer/schedule/tests/test_schedule_editor.py +++ b/wafer/schedule/tests/test_schedule_editor.py @@ -21,7 +21,7 @@ from django.urls import reverse from wafer.pages.models import Page -from wafer.tests.utils import create_user, ChromeTestRunner, FirefoxTestRunner +from wafer.tests.utils import create_user, ChromeTestRunner, FirefoxTestRunner, SELENIUM_WAIT_TIME from wafer.talks.tests.fixtures import create_talk from wafer.talks.models import ACCEPTED @@ -126,14 +126,14 @@ def _start(self): """Helper method to login as admin and load the editor""" self.admin_login() self.driver.get(self.edit_page) - WebDriverWait(self.driver, 10).until( + WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( expected_conditions.presence_of_element_located((By.TAG_NAME, "h1")) ) def test_access_schedule_editor_no_login(self): """Test that the schedule editor isn't accessible if not logged in""" self.driver.get(self.edit_page) - header = WebDriverWait(self.driver, 10).until( + header = WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( expected_conditions.presence_of_element_located((By.TAG_NAME, "h1")) ) self.assertEqual('Django administration', header.text) @@ -148,10 +148,12 @@ def test_access_schedule_editor_no_super(self): """Test that the schedule editor isn't accessible for non-superuser accounts""" self.normal_login() self.driver.get(self.edit_page) - WebDriverWait(self.driver, 10).until( + WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( expected_conditions.presence_of_element_located((By.TAG_NAME, "h1")) ) - error = self.driver.find_element(By.CLASS_NAME, "errornote") + error = WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( + expected_conditions.presence_of_element_located((By.CLASS_NAME, "errornote")) + ) self.assertIn("authenticated as normal", error.text) self.assertIn("not authorized to access this page", error.text) # Check that no admin info has loaded @@ -161,7 +163,9 @@ def test_access_schedule_editor_no_super(self): def test_access_schedule_editor_admin(self): """Test that the schedule editor is accessible for superuser accounts""" self._start() - all_talks_link = self.driver.find_element(By.PARTIAL_LINK_TEXT, "All Talks") + all_talks_link = WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( + expected_conditions.presence_of_element_located((By.PARTIAL_LINK_TEXT, "All Talks")) + ) all_talks_link.click() tab_pane = None for pane in self.driver.find_elements(By.CLASS_NAME, "tab-pane"): @@ -176,7 +180,9 @@ def test_drag_talk(self): self.assertEqual(ScheduleItem.objects.count(), 0) self._start() # partial link text to avoid whitespace fiddling - talks_link = self.driver.find_element(By.PARTIAL_LINK_TEXT, "Unassigned Talks") + talks_link = WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( + expected_conditions.presence_of_element_located((By.PARTIAL_LINK_TEXT, "Unassigned Talks")) + ) talks_link.click() tab_pane = None for pane in self.driver.find_elements(By.CLASS_NAME, "tab-pane"): @@ -196,7 +202,7 @@ def test_drag_talk(self): # Pause briefly to make sure the server has a chance to do stuff actions.pause(0.5) actions.perform() - WebDriverWait(self.driver, 10).until( + WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( expected_conditions.presence_of_element_located((By.CLASS_NAME, "close")) ) self.assertEqual(ScheduleItem.objects.count(), 1) @@ -217,7 +223,7 @@ def test_drag_talk(self): actions.drag_and_drop(source, target) actions.pause(0.5) actions.perform() - WebDriverWait(self.driver, 10).until( + WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( expected_conditions.presence_of_element_located((By.CLASS_NAME, "close")) ) self.assertEqual(ScheduleItem.objects.count(), 2) @@ -232,7 +238,10 @@ def test_drag_page(self): self.assertEqual(ScheduleItem.objects.count(), 0) self._start() # Drag a page from the siderbar to a slot in the schedule - page_link = self.driver.find_element(By.PARTIAL_LINK_TEXT, "Pages") + + page_link = WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( + expected_conditions.presence_of_element_located((By.PARTIAL_LINK_TEXT, "Pages")) + ) page_link.click() tab_pane = None for pane in self.driver.find_elements(By.CLASS_NAME, "tab-pane"): @@ -253,7 +262,7 @@ def test_drag_page(self): actions.drag_and_drop(source, target) actions.pause(0.5) actions.perform() - WebDriverWait(self.driver, 10).until( + WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( expected_conditions.presence_of_element_located((By.CLASS_NAME, "close")) ) self.assertEqual(ScheduleItem.objects.count(), 1) @@ -279,7 +288,7 @@ def test_drag_page(self): actions.drag_and_drop(source, target) actions.pause(0.5) actions.perform() - WebDriverWait(self.driver, 10).until( + WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( expected_conditions.presence_of_element_located((By.CLASS_NAME, "close")) ) self.assertEqual(ScheduleItem.objects.count(), 2) @@ -323,7 +332,9 @@ def test_swicth_day(self): # Load schedule page self._start() # Verify we see the expected schedule items on day 1 - td1 = self.driver.find_element(By.ID, f"scheduleItem{item1.pk}") + td1 = WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( + expected_conditions.presence_of_element_located((By.ID, f"scheduleItem{item1.pk}")) + ) self.assertEqual(td1.tag_name, 'td') td2 = self.driver.find_element(By.ID, f"scheduleItem{item2.pk}") self.assertEqual(td2.tag_name, 'td') @@ -333,12 +344,12 @@ def test_swicth_day(self): buttons = self.driver.find_elements(By.TAG_NAME, 'button') self.assertIn('Sep', buttons[1].text) buttons[1].click() - WebDriverWait(self.driver, 10).until( + WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( expected_conditions.presence_of_element_located((By.CLASS_NAME, "show")) ) days = self.driver.find_elements(By.PARTIAL_LINK_TEXT, "Sep") days[1].click() - WebDriverWait(self.driver, 10).until( + WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( expected_conditions.presence_of_element_located((By.CLASS_NAME, "close")) ) # Verify we see the expected schedule items on day 2 @@ -362,7 +373,9 @@ def test_drag_over_talk(self): item1.save() self._start() # Test dragging a talk over an existing talk - target = self.driver.find_element(By.ID, f"scheduleItem{item1.pk}") + target = WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( + expected_conditions.presence_of_element_located((By.ID, f"scheduleItem{item1.pk}")) + ) talks_link = self.driver.find_element(By.PARTIAL_LINK_TEXT, "Unassigned Talks") talks_link.click() tab_pane = None @@ -414,7 +427,9 @@ def test_drag_over_page(self): item1.save() self._start() # Test dragging a page over an existing page - target = self.driver.find_element(By.ID, f"scheduleItem{item1.pk}") + target = WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( + expected_conditions.presence_of_element_located((By.ID, f"scheduleItem{item1.pk}")) + ) page_link = self.driver.find_element(By.PARTIAL_LINK_TEXT, "Pages") page_link.click() tab_pane = None @@ -462,7 +477,9 @@ def test_adding_clash(self): item2.save() self._start() # Verify that there are no validation errors - validation = self.driver.find_element(By.CLASS_NAME, "alert-danger") + validation = WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( + expected_conditions.presence_of_element_located((By.CLASS_NAME, "alert-danger")) + ) self.assertFalse(validation.is_displayed()) # Drag a talk into a clashing slot target = self.driver.find_element(By.ID, f"scheduleItem{item2.pk}") @@ -507,7 +524,9 @@ def test_removing_clash(self): item2.save() self._start() # Verify that there are validation errors - validation = self.driver.find_element(By.CLASS_NAME, "alert-danger") + validation = WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( + expected_conditions.presence_of_element_located((By.CLASS_NAME, "alert-danger")) + ) self.assertTrue(validation.is_displayed()) error_item = validation.find_element(By.TAG_NAME, "li") self.assertIn('Common speaker', error_item.text) diff --git a/wafer/tests/utils.py b/wafer/tests/utils.py index 4c16dab7..bef71d93 100644 --- a/wafer/tests/utils.py +++ b/wafer/tests/utils.py @@ -52,6 +52,11 @@ def mock_avatar_url(self): return None return "avatar-%s" % self.user.email + +# Time to wait for elements to appear - single constant so we can easily tune it if needed +SELENIUM_WAIT_TIME = 20 + + @tag('selenium') class BaseWebdriverRunner(StaticLiveServerTestCase): @@ -76,7 +81,7 @@ def _login(self, name, password): """Generic login handler""" login_url = reverse('auth_login') self.driver.get(f"{self.live_server_url}{login_url}") - WebDriverWait(self.driver, 10).until( + WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( expected_conditions.presence_of_element_located((By.NAME, "submit")) ) user_field = self.driver.find_element(By.NAME, 'username') @@ -85,7 +90,7 @@ def _login(self, name, password): pass_field.send_keys(password) loginbut = self.driver.find_element(By.NAME, 'submit') loginbut.click() - WebDriverWait(self.driver, 10).until( + WebDriverWait(self.driver, SELENIUM_WAIT_TIME).until( expected_conditions.presence_of_element_located((By.CLASS_NAME, "wafer-profile")) )