Merged in [19432] from lars@eggert.org:

Fix things that selenium deprecated in version 4.
 - Legacy-Id: 19504
Note: SVN reference [19432] has been migrated to Git commit 715b0949cc
This commit is contained in:
Robert Sparks 2021-10-29 19:53:37 +00:00
parent 3a876f26e4
commit 59597794b7
4 changed files with 157 additions and 152 deletions

View file

@ -30,7 +30,7 @@ class EditAuthorsTests(IetfSeleniumTestCase):
# To enter the person, type their name in the select2 search box, wait for the # To enter the person, type their name in the select2 search box, wait for the
# search to offer the result, then press 'enter' to accept the result and close # search to offer the result, then press 'enter' to accept the result and close
# the search input. # the search input.
person_span = form_elt.find_element_by_class_name('select2-chosen') person_span = form_elt.find_element(By.CLASS_NAME, 'select2-chosen')
self.scroll_to_element(person_span) self.scroll_to_element(person_span)
person_span.click() person_span.click()
input = self.driver.switch_to.active_element input = self.driver.switch_to.active_element
@ -46,16 +46,16 @@ class EditAuthorsTests(IetfSeleniumTestCase):
# After the author is selected, the email select options will be populated. # After the author is selected, the email select options will be populated.
# Wait for that, then click on the option corresponding to the requested email. # Wait for that, then click on the option corresponding to the requested email.
# This will only work if the email matches an address for the selected person. # This will only work if the email matches an address for the selected person.
email_select = form_elt.find_element_by_css_selector('select[name$="email"]') email_select = form_elt.find_element(By.CSS_SELECTOR, 'select[name$="email"]')
email_option = self.wait.until( email_option = self.wait.until(
presence_of_element_child_by_css_selector(email_select, 'option[value="{}"]'.format(email)) presence_of_element_child_by_css_selector(email_select, 'option[value="{}"]'.format(email))
) )
email_option.click() # select the email email_option.click() # select the email
# Fill in the affiliation and country. Finally, simple text inputs! # Fill in the affiliation and country. Finally, simple text inputs!
affil_input = form_elt.find_element_by_css_selector('input[name$="affiliation"]') affil_input = form_elt.find_element(By.CSS_SELECTOR, 'input[name$="affiliation"]')
affil_input.send_keys(affiliation) affil_input.send_keys(affiliation)
country_input = form_elt.find_element_by_css_selector('input[name$="country"]') country_input = form_elt.find_element(By.CSS_SELECTOR, 'input[name$="country"]')
country_input.send_keys(country) country_input.send_keys(country)
def _read_author_form(form_elt): def _read_author_form(form_elt):
@ -63,10 +63,10 @@ class EditAuthorsTests(IetfSeleniumTestCase):
Note: returns the Person instance named in the person field, not just their name. Note: returns the Person instance named in the person field, not just their name.
""" """
hidden_person_input = form_elt.find_element_by_css_selector('input[type="text"][name$="person"]') hidden_person_input = form_elt.find_element(By.CSS_SELECTOR, 'input[type="text"][name$="person"]')
email_select = form_elt.find_element_by_css_selector('select[name$="email"]') email_select = form_elt.find_element(By.CSS_SELECTOR, 'select[name$="email"]')
affil_input = form_elt.find_element_by_css_selector('input[name$="affiliation"]') affil_input = form_elt.find_element(By.CSS_SELECTOR, 'input[name$="affiliation"]')
country_input = form_elt.find_element_by_css_selector('input[name$="country"]') country_input = form_elt.find_element(By.CSS_SELECTOR, 'input[name$="country"]')
return ( return (
Person.objects.get(pk=hidden_person_input.get_attribute('value')), Person.objects.get(pk=hidden_person_input.get_attribute('value')),
email_select.get_attribute('value'), email_select.get_attribute('value'),
@ -87,16 +87,16 @@ class EditAuthorsTests(IetfSeleniumTestCase):
self.driver.get(url) self.driver.get(url)
# The draft has one author to start with. Find the list and check the count. # The draft has one author to start with. Find the list and check the count.
authors_list = self.driver.find_element_by_id('authors-list') authors_list = self.driver.find_element(By.ID, 'authors-list')
author_forms = authors_list.find_elements_by_class_name('author-panel') author_forms = authors_list.find_elements(By.CLASS_NAME, 'author-panel')
self.assertEqual(len(author_forms), 1) self.assertEqual(len(author_forms), 1)
# get the "add author" button so we can add blank author forms # get the "add author" button so we can add blank author forms
add_author_button = self.driver.find_element_by_id('add-author-button') add_author_button = self.driver.find_element(By.ID, 'add-author-button')
for index, auth in enumerate(authors): for index, auth in enumerate(authors):
self.scroll_to_element(add_author_button) # Can only click if it's in view! self.scroll_to_element(add_author_button) # Can only click if it's in view!
add_author_button.click() # Create a new form. Automatically scrolls to it. add_author_button.click() # Create a new form. Automatically scrolls to it.
author_forms = authors_list.find_elements_by_class_name('author-panel') author_forms = authors_list.find_elements(By.CLASS_NAME, 'author-panel')
authors_added = index + 1 authors_added = index + 1
self.assertEqual(len(author_forms), authors_added + 1) # Started with 1 author, hence +1 self.assertEqual(len(author_forms), authors_added + 1) # Started with 1 author, hence +1
_fill_in_author_form(author_forms[index + 1], auth.name, str(auth.email()), orgs[index], countries[index]) _fill_in_author_form(author_forms[index + 1], auth.name, str(auth.email()), orgs[index], countries[index])
@ -114,9 +114,9 @@ class EditAuthorsTests(IetfSeleniumTestCase):
) )
# Must provide a "basis" (change reason) # Must provide a "basis" (change reason)
self.driver.find_element_by_id('id_basis').send_keys('change testing') self.driver.find_element(By.ID, 'id_basis').send_keys('change testing')
# Now click the 'submit' button and check that the update was accepted. # Now click the 'submit' button and check that the update was accepted.
submit_button = self.driver.find_element_by_css_selector('button[type="submit"]') submit_button = self.driver.find_element(By.CSS_SELECTOR, 'button[type="submit"]')
self.scroll_to_element(submit_button) self.scroll_to_element(submit_button)
submit_button.click() submit_button.click()
# Wait for redirect to the document_main view # Wait for redirect to the document_main view

View file

@ -34,7 +34,7 @@ class MilestoneTests(IetfSeleniumTestCase):
(By.CSS_SELECTOR, result_selector), (By.CSS_SELECTOR, result_selector),
draft.name draft.name
)) ))
results = self.driver.find_elements_by_css_selector(result_selector) results = self.driver.find_elements(By.CSS_SELECTOR, result_selector)
matching_results = [r for r in results if draft.name in r.text] matching_results = [r for r in results if draft.name in r.text]
self.assertEqual(len(matching_results), 1) self.assertEqual(len(matching_results), 1)
return matching_results[0] return matching_results[0]
@ -61,7 +61,7 @@ class MilestoneTests(IetfSeleniumTestCase):
except TimeoutException: except TimeoutException:
found_expected_text = False found_expected_text = False
self.assertTrue(found_expected_text, 'Milestone never marked as "changed"') self.assertTrue(found_expected_text, 'Milestone never marked as "changed"')
return self.driver.find_element_by_css_selector(milestone_selector) return self.driver.find_element(By.CSS_SELECTOR, milestone_selector)
def test_add_milestone(self): def test_add_milestone(self):
draft = WgDraftFactory() draft = WgDraftFactory()
@ -89,9 +89,9 @@ class MilestoneTests(IetfSeleniumTestCase):
(By.CSS_SELECTOR, 'form#milestones-form div.edit-milestone') (By.CSS_SELECTOR, 'form#milestones-form div.edit-milestone')
)) ))
desc_input = edit_div.find_element_by_css_selector('input[id$="_desc"]') desc_input = edit_div.find_element(By.CSS_SELECTOR, 'input[id$="_desc"]')
due_input = edit_div.find_element_by_css_selector('input[id$="_due"]') due_input = edit_div.find_element(By.CSS_SELECTOR, 'input[id$="_due"]')
draft_input = edit_div.find_element_by_css_selector( draft_input = edit_div.find_element(By.CSS_SELECTOR,
'div.select2-container[id$="id_docs"] input.select2-input' 'div.select2-container[id$="id_docs"] input.select2-input'
) )
@ -149,9 +149,9 @@ class MilestoneTests(IetfSeleniumTestCase):
# Get the prefix used to identify inputs related to this milestone # Get the prefix used to identify inputs related to this milestone
prefix = desc_field.get_attribute('id')[:-4] # -4 to strip off 'desc', leave '-' prefix = desc_field.get_attribute('id')[:-4] # -4 to strip off 'desc', leave '-'
due_field = self.driver.find_element_by_id(prefix + 'due') due_field = self.driver.find_element(By.ID, prefix + 'due')
hidden_drafts_field = self.driver.find_element_by_id(prefix + 'docs') hidden_drafts_field = self.driver.find_element(By.ID, prefix + 'docs')
draft_input = self.driver.find_element_by_css_selector( draft_input = self.driver.find_element(By.CSS_SELECTOR,
'div.select2-container[id*="%s"] input.select2-input' % prefix 'div.select2-container[id*="%s"] input.select2-input' % prefix
) )
self.assertEqual(due_field.get_attribute('value'), milestone.due.strftime('%B %Y')) self.assertEqual(due_field.get_attribute('value'), milestone.due.strftime('%B %Y'))
@ -185,4 +185,4 @@ class MilestoneTests(IetfSeleniumTestCase):
gms = self.group.groupmilestone_set.first() gms = self.group.groupmilestone_set.first()
self.assertEqual(gms.desc, expected_desc) self.assertEqual(gms.desc, expected_desc)
self.assertEqual(gms.due.strftime('%m %Y'), expected_due_date) self.assertEqual(gms.due.strftime('%m %Y'), expected_due_date)
self.assertCountEqual(expected_docs, gms.docs.all()) self.assertCountEqual(expected_docs, gms.docs.all())

View file

@ -110,34 +110,34 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
WebDriverWait(self.driver, 2).until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR, '.edit-meeting-schedule'))) WebDriverWait(self.driver, 2).until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR, '.edit-meeting-schedule')))
self.assertEqual(len(self.driver.find_elements_by_css_selector('.session')), 3) self.assertEqual(len(self.driver.find_elements(By.CSS_SELECTOR, '.session')), 3)
# select - show session info # select - show session info
s2_element = self.driver.find_element_by_css_selector('#session{}'.format(s2.pk)) s2_element = self.driver.find_element(By.CSS_SELECTOR, '#session{}'.format(s2.pk))
s2b_element = self.driver.find_element_by_css_selector('#session{}'.format(s2b.pk)) s2b_element = self.driver.find_element(By.CSS_SELECTOR, '#session{}'.format(s2b.pk))
self.assertNotIn('other-session-selected', s2b_element.get_attribute('class')) self.assertNotIn('other-session-selected', s2b_element.get_attribute('class'))
s2_element.click() s2_element.click()
# other session for group should be flagged for highlighting # other session for group should be flagged for highlighting
s2b_element = self.driver.find_element_by_css_selector('#session{}'.format(s2b.pk)) s2b_element = self.driver.find_element(By.CSS_SELECTOR, '#session{}'.format(s2b.pk))
self.assertIn('other-session-selected', s2b_element.get_attribute('class')) self.assertIn('other-session-selected', s2b_element.get_attribute('class'))
# other session for group should appear in the info panel # other session for group should appear in the info panel
session_info_container = self.driver.find_element_by_css_selector('.session-info-container') session_info_container = self.driver.find_element(By.CSS_SELECTOR, '.session-info-container')
self.assertIn(s2.group.acronym, session_info_container.find_element_by_css_selector(".title").text) self.assertIn(s2.group.acronym, session_info_container.find_element(By.CSS_SELECTOR, ".title").text)
self.assertEqual(session_info_container.find_element_by_css_selector(".other-session .time").text, "not yet scheduled") self.assertEqual(session_info_container.find_element(By.CSS_SELECTOR, ".other-session .time").text, "not yet scheduled")
# deselect # deselect
self.driver.find_element_by_css_selector('.scheduling-panel').click() self.driver.find_element(By.CSS_SELECTOR, '.scheduling-panel').click()
self.assertEqual(session_info_container.find_elements_by_css_selector(".title"), []) self.assertEqual(session_info_container.find_elements(By.CSS_SELECTOR, ".title"), [])
self.assertNotIn('other-session-selected', s2b_element.get_attribute('class')) self.assertNotIn('other-session-selected', s2b_element.get_attribute('class'))
# unschedule # unschedule
# we would like to do # we would like to do
# #
# unassigned_sessions_element = self.driver.find_element_by_css_selector('.unassigned-sessions') # unassigned_sessions_element = self.driver.find_element(By.CSS_SELECTOR, '.unassigned-sessions')
# ActionChains(self.driver).drag_and_drop(s2_element, unassigned_sessions_element).perform() # ActionChains(self.driver).drag_and_drop(s2_element, unassigned_sessions_element).perform()
# #
# but unfortunately, Selenium does not simulate drag and drop events, see # but unfortunately, Selenium does not simulate drag and drop events, see
@ -158,20 +158,20 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
# sorting unassigned # sorting unassigned
sorted_pks = [s.pk for s in sorted([s1, s2, s2b], key=lambda s: (s.group.acronym, s.requested_duration, s.pk))] sorted_pks = [s.pk for s in sorted([s1, s2, s2b], key=lambda s: (s.group.acronym, s.requested_duration, s.pk))]
self.driver.find_element_by_css_selector('[name=sort_unassigned] option[value=name]').click() self.driver.find_element(By.CSS_SELECTOR, '[name=sort_unassigned] option[value=name]').click()
self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions .drop-target #session{} + #session{} + #session{}'.format(*sorted_pks))) self.assertTrue(self.driver.find_element(By.CSS_SELECTOR, '.unassigned-sessions .drop-target #session{} + #session{} + #session{}'.format(*sorted_pks)))
sorted_pks = [s.pk for s in sorted([s1, s2, s2b], key=lambda s: (s.group.parent.acronym, s.group.acronym, s.requested_duration, s.pk))] sorted_pks = [s.pk for s in sorted([s1, s2, s2b], key=lambda s: (s.group.parent.acronym, s.group.acronym, s.requested_duration, s.pk))]
self.driver.find_element_by_css_selector('[name=sort_unassigned] option[value=parent]').click() self.driver.find_element(By.CSS_SELECTOR, '[name=sort_unassigned] option[value=parent]').click()
self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions .drop-target #session{} + #session{}'.format(*sorted_pks))) self.assertTrue(self.driver.find_element(By.CSS_SELECTOR, '.unassigned-sessions .drop-target #session{} + #session{}'.format(*sorted_pks)))
sorted_pks = [s.pk for s in sorted([s1, s2, s2b], key=lambda s: (s.requested_duration, s.group.parent.acronym, s.group.acronym, s.pk))] sorted_pks = [s.pk for s in sorted([s1, s2, s2b], key=lambda s: (s.requested_duration, s.group.parent.acronym, s.group.acronym, s.pk))]
self.driver.find_element_by_css_selector('[name=sort_unassigned] option[value=duration]').click() self.driver.find_element(By.CSS_SELECTOR, '[name=sort_unassigned] option[value=duration]').click()
self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions .drop-target #session{} + #session{}'.format(*sorted_pks))) self.assertTrue(self.driver.find_element(By.CSS_SELECTOR, '.unassigned-sessions .drop-target #session{} + #session{}'.format(*sorted_pks)))
sorted_pks = [s.pk for s in sorted([s1, s2, s2b], key=lambda s: (int(bool(s.comments)), s.group.parent.acronym, s.group.acronym, s.requested_duration, s.pk))] sorted_pks = [s.pk for s in sorted([s1, s2, s2b], key=lambda s: (int(bool(s.comments)), s.group.parent.acronym, s.group.acronym, s.requested_duration, s.pk))]
self.driver.find_element_by_css_selector('[name=sort_unassigned] option[value=comments]').click() self.driver.find_element(By.CSS_SELECTOR, '[name=sort_unassigned] option[value=comments]').click()
self.assertTrue(self.driver.find_element_by_css_selector('.unassigned-sessions .drop-target #session{} + #session{}'.format(*sorted_pks))) self.assertTrue(self.driver.find_element(By.CSS_SELECTOR, '.unassigned-sessions .drop-target #session{} + #session{}'.format(*sorted_pks)))
# schedule # schedule
self.driver.execute_script("jQuery('#session{}').simulateDragDrop({{dropTarget: '#timeslot{} .drop-target'}});".format(s2.pk, slot1.pk)) self.driver.execute_script("jQuery('#session{}').simulateDragDrop({{dropTarget: '#timeslot{} .drop-target'}});".format(s2.pk, slot1.pk))
@ -182,30 +182,30 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
self.assertEqual(assignment.timeslot, slot1) self.assertEqual(assignment.timeslot, slot1)
# timeslot constraint hints when selected # timeslot constraint hints when selected
s1_element = self.driver.find_element_by_css_selector('#session{}'.format(s1.pk)) s1_element = self.driver.find_element(By.CSS_SELECTOR, '#session{}'.format(s1.pk))
s1_element.click() s1_element.click()
# violated due to constraints - both the timeslot and its timeslot label # violated due to constraints - both the timeslot and its timeslot label
self.assertTrue(self.driver.find_elements_by_css_selector('#timeslot{}.would-violate-hint'.format(slot1.pk))) self.assertTrue(self.driver.find_elements(By.CSS_SELECTOR, '#timeslot{}.would-violate-hint'.format(slot1.pk)))
# Find the timeslot label for slot1 - it's the first timeslot in the first room group # Find the timeslot label for slot1 - it's the first timeslot in the first room group
slot1_roomgroup_elt = self.driver.find_element_by_css_selector( slot1_roomgroup_elt = self.driver.find_element(By.CSS_SELECTOR,
'.day-flow .day:first-child .room-group:nth-child(2)' # count from 2 - first-child is the day label '.day-flow .day:first-child .room-group:nth-child(2)' # count from 2 - first-child is the day label
) )
self.assertTrue( self.assertTrue(
slot1_roomgroup_elt.find_elements_by_css_selector( slot1_roomgroup_elt.find_elements(By.CSS_SELECTOR,
'.time-header > .time-label.would-violate-hint:first-child' '.time-header > .time-label.would-violate-hint:first-child'
), ),
'Timeslot header label should show a would-violate hint for a constraint violation' 'Timeslot header label should show a would-violate hint for a constraint violation'
) )
# violated due to missing capacity # violated due to missing capacity
self.assertTrue(self.driver.find_elements_by_css_selector('#timeslot{}.would-violate-hint'.format(slot3.pk))) self.assertTrue(self.driver.find_elements(By.CSS_SELECTOR, '#timeslot{}.would-violate-hint'.format(slot3.pk)))
# Find the timeslot label for slot3 - it's the second timeslot in the second room group # Find the timeslot label for slot3 - it's the second timeslot in the second room group
slot3_roomgroup_elt = self.driver.find_element_by_css_selector( slot3_roomgroup_elt = self.driver.find_element(By.CSS_SELECTOR,
'.day-flow .day:first-child .room-group:nth-child(3)' # count from 2 - first-child is the day label '.day-flow .day:first-child .room-group:nth-child(3)' # count from 2 - first-child is the day label
) )
self.assertFalse( self.assertFalse(
slot3_roomgroup_elt.find_elements_by_css_selector( slot3_roomgroup_elt.find_elements(By.CSS_SELECTOR,
'.time-header > .time-label.would-violate-hint:nth-child(2)' '.time-header > .time-label.would-violate-hint:nth-child(2)'
), ),
'Timeslot header label should not show a would-violate hint for room capacity violation' 'Timeslot header label should not show a would-violate hint for room capacity violation'
@ -220,15 +220,15 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
self.assertEqual(assignment.timeslot, slot2) self.assertEqual(assignment.timeslot, slot2)
# too many attendees warning # too many attendees warning
self.assertTrue(self.driver.find_elements_by_css_selector('#session{}.too-many-attendees'.format(s2.pk))) self.assertTrue(self.driver.find_elements(By.CSS_SELECTOR, '#session{}.too-many-attendees'.format(s2.pk)))
# overfull timeslot # overfull timeslot
self.assertTrue(self.driver.find_elements_by_css_selector('#timeslot{}.overfull'.format(slot2.pk))) self.assertTrue(self.driver.find_elements(By.CSS_SELECTOR, '#timeslot{}.overfull'.format(slot2.pk)))
# constraint hints # constraint hints
s1_element.click() s1_element.click()
self.assertIn('would-violate-hint', s2_element.get_attribute('class')) self.assertIn('would-violate-hint', s2_element.get_attribute('class'))
constraint_element = s2_element.find_element_by_css_selector(".constraints span[data-sessions=\"{}\"].would-violate-hint".format(s1.pk)) constraint_element = s2_element.find_element(By.CSS_SELECTOR, ".constraints span[data-sessions=\"{}\"].would-violate-hint".format(s1.pk))
self.assertTrue(constraint_element.is_displayed()) self.assertTrue(constraint_element.is_displayed())
# current constraint violations # current constraint violations
@ -236,12 +236,12 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
WebDriverWait(self.driver, 2).until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR, '#timeslot{} #session{}'.format(slot1.pk, s1.pk)))) WebDriverWait(self.driver, 2).until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR, '#timeslot{} #session{}'.format(slot1.pk, s1.pk))))
constraint_element = s2_element.find_element_by_css_selector(".constraints span[data-sessions=\"{}\"].violated-hint".format(s1.pk)) constraint_element = s2_element.find_element(By.CSS_SELECTOR, ".constraints span[data-sessions=\"{}\"].violated-hint".format(s1.pk))
self.assertTrue(constraint_element.is_displayed()) self.assertTrue(constraint_element.is_displayed())
# hide sessions in area # hide sessions in area
self.assertTrue(s1_element.is_displayed()) self.assertTrue(s1_element.is_displayed())
self.driver.find_element_by_css_selector(".session-parent-toggles [value=\"{}\"]".format(s1.group.parent.acronym)).click() self.driver.find_element(By.CSS_SELECTOR, ".session-parent-toggles [value=\"{}\"]".format(s1.group.parent.acronym)).click()
self.assertTrue(s1_element.is_displayed()) # should still be displayed self.assertTrue(s1_element.is_displayed()) # should still be displayed
self.assertIn('hidden-parent', s1_element.get_attribute('class'), self.assertIn('hidden-parent', s1_element.get_attribute('class'),
'Session should be hidden when parent disabled') 'Session should be hidden when parent disabled')
@ -249,7 +249,7 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
self.assertNotIn('selected', s1_element.get_attribute('class'), self.assertNotIn('selected', s1_element.get_attribute('class'),
'Session should not be selectable when parent disabled') 'Session should not be selectable when parent disabled')
self.driver.find_element_by_css_selector(".session-parent-toggles [value=\"{}\"]".format(s1.group.parent.acronym)).click() self.driver.find_element(By.CSS_SELECTOR, ".session-parent-toggles [value=\"{}\"]".format(s1.group.parent.acronym)).click()
self.assertTrue(s1_element.is_displayed()) self.assertTrue(s1_element.is_displayed())
self.assertNotIn('hidden-parent', s1_element.get_attribute('class'), self.assertNotIn('hidden-parent', s1_element.get_attribute('class'),
'Session should not be hidden when parent enabled') 'Session should not be hidden when parent enabled')
@ -258,32 +258,32 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
'Session should be selectable when parent enabled') 'Session should be selectable when parent enabled')
# hide timeslots # hide timeslots
self.driver.find_element_by_css_selector(".timeslot-group-toggles button").click() self.driver.find_element(By.CSS_SELECTOR, ".timeslot-group-toggles button").click()
self.assertTrue(self.driver.find_element_by_css_selector("#timeslot-group-toggles-modal").is_displayed()) self.assertTrue(self.driver.find_element(By.CSS_SELECTOR, "#timeslot-group-toggles-modal").is_displayed())
self.driver.find_element_by_css_selector("#timeslot-group-toggles-modal [value=\"{}\"]".format("ts-group-{}-{}".format(slot2.time.strftime("%Y%m%d-%H%M"), int(slot2.duration.total_seconds() / 60)))).click() self.driver.find_element(By.CSS_SELECTOR, "#timeslot-group-toggles-modal [value=\"{}\"]".format("ts-group-{}-{}".format(slot2.time.strftime("%Y%m%d-%H%M"), int(slot2.duration.total_seconds() / 60)))).click()
self.driver.find_element_by_css_selector("#timeslot-group-toggles-modal [data-dismiss=\"modal\"]").click() self.driver.find_element(By.CSS_SELECTOR, "#timeslot-group-toggles-modal [data-dismiss=\"modal\"]").click()
self.assertTrue(not self.driver.find_element_by_css_selector("#timeslot-group-toggles-modal").is_displayed()) self.assertTrue(not self.driver.find_element(By.CSS_SELECTOR, "#timeslot-group-toggles-modal").is_displayed())
# swap days # swap days
self.driver.find_element_by_css_selector(".day .swap-days[data-dayid=\"{}\"]".format(slot4.time.date().isoformat())).click() self.driver.find_element(By.CSS_SELECTOR, ".day .swap-days[data-dayid=\"{}\"]".format(slot4.time.date().isoformat())).click()
self.assertTrue(self.driver.find_element_by_css_selector("#swap-days-modal").is_displayed()) self.assertTrue(self.driver.find_element(By.CSS_SELECTOR, "#swap-days-modal").is_displayed())
self.driver.find_element_by_css_selector("#swap-days-modal input[name=\"target_day\"][value=\"{}\"]".format(slot1.time.date().isoformat())).click() self.driver.find_element(By.CSS_SELECTOR, "#swap-days-modal input[name=\"target_day\"][value=\"{}\"]".format(slot1.time.date().isoformat())).click()
self.driver.find_element_by_css_selector("#swap-days-modal button[type=\"submit\"]").click() self.driver.find_element(By.CSS_SELECTOR, "#swap-days-modal button[type=\"submit\"]").click()
self.assertTrue(self.driver.find_elements_by_css_selector('#timeslot{} #session{}'.format(slot4.pk, s1.pk)), self.assertTrue(self.driver.find_elements(By.CSS_SELECTOR, '#timeslot{} #session{}'.format(slot4.pk, s1.pk)),
'Session s1 should have moved to second meeting day') 'Session s1 should have moved to second meeting day')
# swap timeslot column - put session in a differently-timed timeslot # swap timeslot column - put session in a differently-timed timeslot
self.driver.find_element_by_css_selector( self.driver.find_element(By.CSS_SELECTOR,
'.day .swap-timeslot-col[data-timeslot-pk="{}"]'.format(slot1b.pk) '.day .swap-timeslot-col[data-timeslot-pk="{}"]'.format(slot1b.pk)
).click() # open modal on the second timeslot for room1 ).click() # open modal on the second timeslot for room1
self.assertTrue(self.driver.find_element_by_css_selector("#swap-timeslot-col-modal").is_displayed()) self.assertTrue(self.driver.find_element(By.CSS_SELECTOR, "#swap-timeslot-col-modal").is_displayed())
self.driver.find_element_by_css_selector( self.driver.find_element(By.CSS_SELECTOR,
'#swap-timeslot-col-modal input[name="target_timeslot"][value="{}"]'.format(slot4.pk) '#swap-timeslot-col-modal input[name="target_timeslot"][value="{}"]'.format(slot4.pk)
).click() # select room1 timeslot that has a session in it ).click() # select room1 timeslot that has a session in it
self.driver.find_element_by_css_selector('#swap-timeslot-col-modal button[type="submit"]').click() self.driver.find_element(By.CSS_SELECTOR, '#swap-timeslot-col-modal button[type="submit"]').click()
self.assertTrue(self.driver.find_elements_by_css_selector('#timeslot{} #session{}'.format(slot1b.pk, s1.pk)), self.assertTrue(self.driver.find_elements(By.CSS_SELECTOR, '#timeslot{} #session{}'.format(slot1b.pk, s1.pk)),
'Session s1 should have moved to second timeslot on first meeting day') 'Session s1 should have moved to second timeslot on first meeting day')
def test_past_flags(self): def test_past_flags(self):
@ -351,19 +351,19 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
self.login(username=meeting.schedule.owner.user.username) self.login(username=meeting.schedule.owner.user.username)
self.driver.get(url) self.driver.get(url)
past_flags = self.driver.find_elements_by_css_selector( past_flags = self.driver.find_elements(By.CSS_SELECTOR,
','.join('#timeslot{} .past-flag'.format(ts.pk) for ts in past_timeslots) ','.join('#timeslot{} .past-flag'.format(ts.pk) for ts in past_timeslots)
) )
self.assertGreaterEqual(len(past_flags), len(past_timeslots) + len(past_sessions), self.assertGreaterEqual(len(past_flags), len(past_timeslots) + len(past_sessions),
'Expected at least one flag for each past timeslot and session') 'Expected at least one flag for each past timeslot and session')
now_flags = self.driver.find_elements_by_css_selector( now_flags = self.driver.find_elements(By.CSS_SELECTOR,
','.join('#timeslot{} .past-flag'.format(ts.pk) for ts in now_timeslots) ','.join('#timeslot{} .past-flag'.format(ts.pk) for ts in now_timeslots)
) )
self.assertGreaterEqual(len(now_flags), len(now_timeslots) + len(now_sessions), self.assertGreaterEqual(len(now_flags), len(now_timeslots) + len(now_sessions),
'Expected at least one flag for each "now" timeslot and session') 'Expected at least one flag for each "now" timeslot and session')
future_flags = self.driver.find_elements_by_css_selector( future_flags = self.driver.find_elements(By.CSS_SELECTOR,
','.join('#timeslot{} .past-flag'.format(ts.pk) for ts in future_timeslots) ','.join('#timeslot{} .past-flag'.format(ts.pk) for ts in future_timeslots)
) )
self.assertGreaterEqual(len(future_flags), len(future_timeslots) + len(future_sessions), self.assertGreaterEqual(len(future_flags), len(future_timeslots) + len(future_sessions),
@ -417,21 +417,21 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
self.login(username=meeting.schedule.owner.user.username) self.login(username=meeting.schedule.owner.user.username)
self.driver.get(url) self.driver.get(url)
past_swap_days_buttons = self.driver.find_elements_by_css_selector( past_swap_days_buttons = self.driver.find_elements(By.CSS_SELECTOR,
','.join( ','.join(
'.swap-days[data-start="{}"]'.format(ts.time.date().isoformat()) for ts in past_timeslots '.swap-days[data-start="{}"]'.format(ts.time.date().isoformat()) for ts in past_timeslots
) )
) )
self.assertEqual(len(past_swap_days_buttons), len(past_timeslots), 'Missing past swap days buttons') self.assertEqual(len(past_swap_days_buttons), len(past_timeslots), 'Missing past swap days buttons')
future_swap_days_buttons = self.driver.find_elements_by_css_selector( future_swap_days_buttons = self.driver.find_elements(By.CSS_SELECTOR,
','.join( ','.join(
'.swap-days[data-start="{}"]'.format(ts.time.date().isoformat()) for ts in future_timeslots '.swap-days[data-start="{}"]'.format(ts.time.date().isoformat()) for ts in future_timeslots
) )
) )
self.assertEqual(len(future_swap_days_buttons), len(future_timeslots), 'Missing future swap days buttons') self.assertEqual(len(future_swap_days_buttons), len(future_timeslots), 'Missing future swap days buttons')
now_swap_days_buttons = self.driver.find_elements_by_css_selector( now_swap_days_buttons = self.driver.find_elements(By.CSS_SELECTOR,
','.join( ','.join(
'.swap-days[data-start="{}"]'.format(ts.time.date().isoformat()) for ts in now_timeslots '.swap-days[data-start="{}"]'.format(ts.time.date().isoformat()) for ts in now_timeslots
) )
@ -475,7 +475,7 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
self.fail('Modal never appeared') self.fail('Modal never appeared')
self.assertFalse( self.assertFalse(
any(radio.is_enabled() any(radio.is_enabled()
for radio in modal.find_elements_by_css_selector(','.join( for radio in modal.find_elements(By.CSS_SELECTOR, ','.join(
'input[name="target_day"][value="{}"]'.format(ts.time.date().isoformat()) for ts in past_timeslots) 'input[name="target_day"][value="{}"]'.format(ts.time.date().isoformat()) for ts in past_timeslots)
)), )),
'Past day is enabled in swap-days modal for official schedule', 'Past day is enabled in swap-days modal for official schedule',
@ -484,14 +484,14 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
enabled_timeslots = (ts for ts in future_timeslots if ts != future_timeslots[clicked_index]) enabled_timeslots = (ts for ts in future_timeslots if ts != future_timeslots[clicked_index])
self.assertTrue( self.assertTrue(
all(radio.is_enabled() all(radio.is_enabled()
for radio in modal.find_elements_by_css_selector(','.join( for radio in modal.find_elements(By.CSS_SELECTOR, ','.join(
'input[name="target_day"][value="{}"]'.format(ts.time.date().isoformat()) for ts in enabled_timeslots) 'input[name="target_day"][value="{}"]'.format(ts.time.date().isoformat()) for ts in enabled_timeslots)
)), )),
'Future day is not enabled in swap-days modal for official schedule', 'Future day is not enabled in swap-days modal for official schedule',
) )
self.assertFalse( self.assertFalse(
any(radio.is_enabled() any(radio.is_enabled()
for radio in modal.find_elements_by_css_selector(','.join( for radio in modal.find_elements(By.CSS_SELECTOR, ','.join(
'input[name="target_day"][value="{}"]'.format(ts.time.date().isoformat()) for ts in now_timeslots) 'input[name="target_day"][value="{}"]'.format(ts.time.date().isoformat()) for ts in now_timeslots)
)), )),
'"Now" day is enabled in swap-days modal for official schedule', '"Now" day is enabled in swap-days modal for official schedule',
@ -533,21 +533,21 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
self.login(username=meeting.schedule.owner.user.username) self.login(username=meeting.schedule.owner.user.username)
self.driver.get(url) self.driver.get(url)
past_swap_ts_buttons = self.driver.find_elements_by_css_selector( past_swap_ts_buttons = self.driver.find_elements(By.CSS_SELECTOR,
','.join( ','.join(
'.swap-timeslot-col[data-start="{}"]'.format(ts.utc_start_time().isoformat()) for ts in past_timeslots '.swap-timeslot-col[data-start="{}"]'.format(ts.utc_start_time().isoformat()) for ts in past_timeslots
) )
) )
self.assertEqual(len(past_swap_ts_buttons), len(past_timeslots), 'Missing past swap timeslot col buttons') self.assertEqual(len(past_swap_ts_buttons), len(past_timeslots), 'Missing past swap timeslot col buttons')
future_swap_ts_buttons = self.driver.find_elements_by_css_selector( future_swap_ts_buttons = self.driver.find_elements(By.CSS_SELECTOR,
','.join( ','.join(
'.swap-timeslot-col[data-start="{}"]'.format(ts.utc_start_time().isoformat()) for ts in future_timeslots '.swap-timeslot-col[data-start="{}"]'.format(ts.utc_start_time().isoformat()) for ts in future_timeslots
) )
) )
self.assertEqual(len(future_swap_ts_buttons), len(future_timeslots), 'Missing future swap timeslot col buttons') self.assertEqual(len(future_swap_ts_buttons), len(future_timeslots), 'Missing future swap timeslot col buttons')
now_swap_ts_buttons = self.driver.find_elements_by_css_selector( now_swap_ts_buttons = self.driver.find_elements(By.CSS_SELECTOR,
','.join( ','.join(
'.swap-timeslot-col[data-start="{}"]'.format(ts.utc_start_time().isoformat()) for ts in now_timeslots '.swap-timeslot-col[data-start="{}"]'.format(ts.utc_start_time().isoformat()) for ts in now_timeslots
) )
@ -590,7 +590,7 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
self.fail('Modal never appeared') self.fail('Modal never appeared')
self.assertFalse( self.assertFalse(
any(radio.is_enabled() any(radio.is_enabled()
for radio in modal.find_elements_by_css_selector(','.join( for radio in modal.find_elements(By.CSS_SELECTOR, ','.join(
'input[name="target_timeslot"][value="{}"]'.format(ts.pk) for ts in past_timeslots) 'input[name="target_timeslot"][value="{}"]'.format(ts.pk) for ts in past_timeslots)
)), )),
'Past timeslot is enabled in swap-timeslot-col modal for official schedule', 'Past timeslot is enabled in swap-timeslot-col modal for official schedule',
@ -599,14 +599,14 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
enabled_timeslots = (ts for ts in future_timeslots if ts != future_timeslots[clicked_index]) enabled_timeslots = (ts for ts in future_timeslots if ts != future_timeslots[clicked_index])
self.assertTrue( self.assertTrue(
all(radio.is_enabled() all(radio.is_enabled()
for radio in modal.find_elements_by_css_selector(','.join( for radio in modal.find_elements(By.CSS_SELECTOR, ','.join(
'input[name="target_timeslot"][value="{}"]'.format(ts.pk) for ts in enabled_timeslots) 'input[name="target_timeslot"][value="{}"]'.format(ts.pk) for ts in enabled_timeslots)
)), )),
'Future timeslot is not enabled in swap-timeslot-col modal for official schedule', 'Future timeslot is not enabled in swap-timeslot-col modal for official schedule',
) )
self.assertFalse( self.assertFalse(
any(radio.is_enabled() any(radio.is_enabled()
for radio in modal.find_elements_by_css_selector(','.join( for radio in modal.find_elements(By.CSS_SELECTOR, ','.join(
'input[name="target_timeslot"][value="{}"]'.format(ts.pk) for ts in now_timeslots) 'input[name="target_timeslot"][value="{}"]'.format(ts.pk) for ts in now_timeslots)
)), )),
'"Now" timeslot is enabled in swap-timeslot-col modal for official schedule', '"Now" timeslot is enabled in swap-timeslot-col modal for official schedule',
@ -625,7 +625,7 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
def sort_by_position(driver, sessions): def sort_by_position(driver, sessions):
"""Helper to sort sessions by the position of their session element in the unscheduled box""" """Helper to sort sessions by the position of their session element in the unscheduled box"""
def _sort_key(sess): def _sort_key(sess):
elt = driver.find_element_by_id('session{}'.format(sess.pk)) elt = driver.find_element(By.ID, 'session{}'.format(sess.pk))
return (elt.location['y'], elt.location['x']) return (elt.location['y'], elt.location['x'])
return sorted(sessions, key=_sort_key) return sorted(sessions, key=_sort_key)
@ -687,10 +687,10 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
self.login('secretary') self.login('secretary')
self.driver.get(url) self.driver.get(url)
select = self.driver.find_element_by_name('sort_unassigned') select = self.driver.find_element(By.NAME, 'sort_unassigned')
options = { options = {
opt.get_attribute('value'): opt opt.get_attribute('value'): opt
for opt in select.find_elements_by_tag_name('option') for opt in select.find_elements(By.TAG_NAME, 'option')
} }
# check sorting by name # check sorting by name
@ -782,10 +782,10 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
self.driver.get(url) self.driver.get(url)
# Check that the drop target for unassigned sessions is actually empty # Check that the drop target for unassigned sessions is actually empty
drop_target = self.driver.find_element_by_css_selector( drop_target = self.driver.find_element(By.CSS_SELECTOR,
'.unassigned-sessions .drop-target' '.unassigned-sessions .drop-target'
) )
self.assertEqual(len(drop_target.find_elements_by_class_name('session')), 0, self.assertEqual(len(drop_target.find_elements(By.CLASS_NAME, 'session')), 0,
'Unassigned sessions box is not empty, test is broken') 'Unassigned sessions box is not empty, test is broken')
# Check that the drop target has non-zero size # Check that the drop target has non-zero size
@ -829,7 +829,7 @@ class EditMeetingScheduleTests(IetfSeleniumTestCase):
kwargs=dict(num=meeting.number, owner=schedule.owner.email(), name=schedule.name)) kwargs=dict(num=meeting.number, owner=schedule.owner.email(), name=schedule.name))
self.login(schedule.owner.user.username) self.login(schedule.owner.user.username)
self.driver.get(url) self.driver.get(url)
session_elements = [self.driver.find_element_by_css_selector(f'#session{sess.pk}') for sess in sessions] session_elements = [self.driver.find_element(By.CSS_SELECTOR, f'#session{sess.pk}') for sess in sessions]
session_elements[0].click() session_elements[0].click()
# All conflicting sessions should be flagged with the would-violate-hint class. # All conflicting sessions should be flagged with the would-violate-hint class.
@ -864,20 +864,20 @@ class ScheduleEditTests(IetfSeleniumTestCase):
# driver.get() will wait for scripts to finish, but not ajax # driver.get() will wait for scripts to finish, but not ajax
# requests. Wait for completion of the permissions check: # requests. Wait for completion of the permissions check:
read_only_note = self.driver.find_element_by_id('read_only') read_only_note = self.driver.find_element(By.ID, 'read_only')
WebDriverWait(self.driver, 10).until(expected_conditions.invisibility_of_element(read_only_note), "Read-only schedule") WebDriverWait(self.driver, 10).until(expected_conditions.invisibility_of_element(read_only_note), "Read-only schedule")
s1 = Session.objects.filter(group__acronym='mars', meeting=meeting).first() s1 = Session.objects.filter(group__acronym='mars', meeting=meeting).first()
selector = "#session_{}".format(s1.pk) selector = "#session_{}".format(s1.pk)
WebDriverWait(self.driver, 30).until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR, selector)), "Did not find %s"%selector) WebDriverWait(self.driver, 30).until(expected_conditions.presence_of_element_located((By.CSS_SELECTOR, selector)), "Did not find %s"%selector)
self.assertEqual(self.driver.find_elements_by_css_selector("#sortable-list #session_{}".format(s1.pk)), []) self.assertEqual(self.driver.find_elements(By.CSS_SELECTOR, "#sortable-list #session_{}".format(s1.pk)), [])
element = self.driver.find_element_by_id('session_{}'.format(s1.pk)) element = self.driver.find_element(By.ID, 'session_{}'.format(s1.pk))
target = self.driver.find_element_by_id('sortable-list') target = self.driver.find_element(By.ID, 'sortable-list')
ActionChains(self.driver).drag_and_drop(element,target).perform() ActionChains(self.driver).drag_and_drop(element,target).perform()
self.assertTrue(self.driver.find_elements_by_css_selector("#sortable-list #session_{}".format(s1.pk))) self.assertTrue(self.driver.find_elements(By.CSS_SELECTOR, "#sortable-list #session_{}".format(s1.pk)))
time.sleep(0.1) # The API that modifies the database runs async time.sleep(0.1) # The API that modifies the database runs async
@ -905,8 +905,8 @@ class SlideReorderTests(IetfSeleniumTestCase):
self.secr_login() self.secr_login()
self.driver.get(url) self.driver.get(url)
#debug.show('unicode(self.driver.page_source)') #debug.show('unicode(self.driver.page_source)')
second = self.driver.find_element_by_css_selector('#slides tr:nth-child(2)') second = self.driver.find_element(By.CSS_SELECTOR, '#slides tr:nth-child(2)')
third = self.driver.find_element_by_css_selector('#slides tr:nth-child(3)') third = self.driver.find_element(By.CSS_SELECTOR, '#slides tr:nth-child(3)')
ActionChains(self.driver).drag_and_drop(second,third).perform() ActionChains(self.driver).drag_and_drop(second,third).perform()
time.sleep(0.1) # The API that modifies the database runs async time.sleep(0.1) # The API that modifies the database runs async
@ -1003,7 +1003,7 @@ class AgendaTests(IetfSeleniumTestCase):
self.driver.get(self.absreverse('ietf.meeting.views.agenda') + querystring) self.driver.get(self.absreverse('ietf.meeting.views.agenda') + querystring)
self.assert_agenda_item_visibility(visible_groups) self.assert_agenda_item_visibility(visible_groups)
self.assert_agenda_view_filter_matches_ics_filter(querystring) self.assert_agenda_view_filter_matches_ics_filter(querystring)
weekview_iframe = self.driver.find_element_by_id('weekview') weekview_iframe = self.driver.find_element(By.ID, 'weekview')
if len(querystring) == 0: if len(querystring) == 0:
self.assertFalse(weekview_iframe.is_displayed(), 'Weekview should be hidden when filters off') self.assertFalse(weekview_iframe.is_displayed(), 'Weekview should be hidden when filters off')
else: else:
@ -1184,7 +1184,7 @@ class AgendaTests(IetfSeleniumTestCase):
for item in self.get_expected_items(): for item in self.get_expected_items():
row_id = self.row_id_for_item(item) row_id = self.row_id_for_item(item)
try: try:
item_row = self.driver.find_element_by_id(row_id) item_row = self.driver.find_element(By.ID, row_id)
except NoSuchElementException: except NoSuchElementException:
item_row = None item_row = None
self.assertIsNotNone(item_row, 'No row for schedule item "%s"' % row_id) self.assertIsNotNone(item_row, 'No row for schedule item "%s"' % row_id)
@ -1205,7 +1205,7 @@ class AgendaTests(IetfSeleniumTestCase):
label = 'Free Slot' label = 'Free Slot'
try: try:
item_div = self.driver.find_element_by_xpath('//div/span[contains(text(),"%s")]/..' % label) item_div = self.driver.find_element(By.XPATH, '//div/span[contains(text(),"%s")]/..' % label)
except NoSuchElementException: except NoSuchElementException:
item_div = None item_div = None
@ -1479,7 +1479,7 @@ class AgendaTests(IetfSeleniumTestCase):
ics_url = self.absreverse('ietf.meeting.views.agenda_ical') ics_url = self.absreverse('ietf.meeting.views.agenda_ical')
# parse out the events # parse out the events
agenda_rows = self.driver.find_elements_by_css_selector('[id^="row-"]') agenda_rows = self.driver.find_elements(By.CSS_SELECTOR, '[id^="row-"]')
visible_rows = [r for r in agenda_rows if r.is_displayed()] visible_rows = [r for r in agenda_rows if r.is_displayed()]
sessions = [self.session_from_agenda_row_id(row.get_attribute("id")) sessions = [self.session_from_agenda_row_id(row.get_attribute("id"))
for row in visible_rows] for row in visible_rows]
@ -1509,7 +1509,7 @@ class AgendaTests(IetfSeleniumTestCase):
self.driver.get(url) self.driver.get(url)
# modal should start hidden # modal should start hidden
modal_div = self.driver.find_element_by_css_selector('div#modal-%s' % slug) modal_div = self.driver.find_element(By.CSS_SELECTOR, 'div#modal-%s' % slug)
self.assertFalse(modal_div.is_displayed()) self.assertFalse(modal_div.is_displayed())
# Click the 'materials' button # Click the 'materials' button
@ -1534,7 +1534,7 @@ class AgendaTests(IetfSeleniumTestCase):
) )
self.assertGreater(not_deleted_slides.count(), 0) # make sure this isn't a pointless test self.assertGreater(not_deleted_slides.count(), 0) # make sure this isn't a pointless test
for slide in not_deleted_slides: for slide in not_deleted_slides:
anchor = self.driver.find_element_by_xpath('//a[text()="%s"]' % slide.title) anchor = self.driver.find_element(By.XPATH, '//a[text()="%s"]' % slide.title)
self.assertIsNotNone(anchor) self.assertIsNotNone(anchor)
deleted_slides = session.materials.filter( deleted_slides = session.materials.filter(
@ -1543,7 +1543,7 @@ class AgendaTests(IetfSeleniumTestCase):
self.assertGreater(deleted_slides.count(), 0) # make sure this isn't a pointless test self.assertGreater(deleted_slides.count(), 0) # make sure this isn't a pointless test
for slide in deleted_slides: for slide in deleted_slides:
with self.assertRaises(NoSuchElementException): with self.assertRaises(NoSuchElementException):
self.driver.find_element_by_xpath('//a[text()="%s"]' % slide.title) self.driver.find_element(By.XPATH, '//a[text()="%s"]' % slide.title)
# Now close the modal # Now close the modal
close_modal_button = WebDriverWait(self.driver, 2).until( close_modal_button = WebDriverWait(self.driver, 2).until(
@ -1588,7 +1588,7 @@ class AgendaTests(IetfSeleniumTestCase):
self.assertNotIn(newly_deleted_slide, not_deleted_slides) self.assertNotIn(newly_deleted_slide, not_deleted_slides)
self.assertIn(newly_undeleted_slide, not_deleted_slides) self.assertIn(newly_undeleted_slide, not_deleted_slides)
for slide in not_deleted_slides: for slide in not_deleted_slides:
anchor = self.driver.find_element_by_xpath('//a[text()="%s"]' % slide.title) anchor = self.driver.find_element(By.XPATH, '//a[text()="%s"]' % slide.title)
self.assertIsNotNone(anchor) self.assertIsNotNone(anchor)
deleted_slides = session.materials.filter( deleted_slides = session.materials.filter(
@ -1598,7 +1598,7 @@ class AgendaTests(IetfSeleniumTestCase):
self.assertNotIn(newly_undeleted_slide, deleted_slides) self.assertNotIn(newly_undeleted_slide, deleted_slides)
for slide in deleted_slides: for slide in deleted_slides:
with self.assertRaises(NoSuchElementException): with self.assertRaises(NoSuchElementException):
self.driver.find_element_by_xpath('//a[text()="%s"]' % slide.title) self.driver.find_element(By.XPATH, '//a[text()="%s"]' % slide.title)
def test_agenda_time_zone_selection(self): def test_agenda_time_zone_selection(self):
self.assertNotEqual(self.meeting.time_zone, 'UTC', 'Meeting time zone must not be UTC') self.assertNotEqual(self.meeting.time_zone, 'UTC', 'Meeting time zone must not be UTC')
@ -1615,14 +1615,14 @@ class AgendaTests(IetfSeleniumTestCase):
) )
) )
tz_select_input = self.driver.find_element_by_id('timezone-select') tz_select_input = self.driver.find_element(By.ID, 'timezone-select')
meeting_tz_link = self.driver.find_element_by_id('meeting-timezone') meeting_tz_link = self.driver.find_element(By.ID, 'meeting-timezone')
local_tz_link = self.driver.find_element_by_id('local-timezone') local_tz_link = self.driver.find_element(By.ID, 'local-timezone')
utc_tz_link = self.driver.find_element_by_id('utc-timezone') utc_tz_link = self.driver.find_element(By.ID, 'utc-timezone')
tz_displays = self.driver.find_elements_by_css_selector('.current-tz') tz_displays = self.driver.find_elements(By.CSS_SELECTOR, '.current-tz')
self.assertGreaterEqual(len(tz_displays), 1) self.assertGreaterEqual(len(tz_displays), 1)
# we'll check that all current-tz elements are updated, but first check that at least one is in the nav sidebar # we'll check that all current-tz elements are updated, but first check that at least one is in the nav sidebar
self.assertIsNotNone(self.driver.find_element_by_css_selector('.nav .current-tz')) self.assertIsNotNone(self.driver.find_element(By.CSS_SELECTOR, '.nav .current-tz'))
# Moment.js guesses local time zone based on the behavior of Selenium's web client. This seems # Moment.js guesses local time zone based on the behavior of Selenium's web client. This seems
# to inherit Django's settings.TIME_ZONE but I don't know whether that's guaranteed to be consistent. # to inherit Django's settings.TIME_ZONE but I don't know whether that's guaranteed to be consistent.
@ -1631,9 +1631,9 @@ class AgendaTests(IetfSeleniumTestCase):
self.assertNotEqual(self.meeting.time_zone, local_tz, 'Meeting time zone must not be local time zone') self.assertNotEqual(self.meeting.time_zone, local_tz, 'Meeting time zone must not be local time zone')
self.assertNotEqual(local_tz, 'UTC', 'Local time zone must not be UTC') self.assertNotEqual(local_tz, 'UTC', 'Local time zone must not be UTC')
meeting_tz_opt = tz_select_input.find_element_by_css_selector('option[value="%s"]' % self.meeting.time_zone) meeting_tz_opt = tz_select_input.find_element(By.CSS_SELECTOR, 'option[value="%s"]' % self.meeting.time_zone)
local_tz_opt = tz_select_input.find_element_by_css_selector('option[value="%s"]' % local_tz) local_tz_opt = tz_select_input.find_element(By.CSS_SELECTOR, 'option[value="%s"]' % local_tz)
utc_tz_opt = tz_select_input.find_element_by_css_selector('option[value="UTC"]') utc_tz_opt = tz_select_input.find_element(By.CSS_SELECTOR, 'option[value="UTC"]')
# Should start off in meeting time zone # Should start off in meeting time zone
self.assertTrue(meeting_tz_opt.is_selected()) self.assertTrue(meeting_tz_opt.is_selected())
@ -1742,20 +1742,20 @@ class AgendaTests(IetfSeleniumTestCase):
# Verify that elements are all updated when the filters change. That the correct elements # Verify that elements are all updated when the filters change. That the correct elements
# have the appropriate classes is a separate test. # have the appropriate classes is a separate test.
elements_to_check = self.driver.find_elements_by_css_selector('.agenda-link.filterable') elements_to_check = self.driver.find_elements(By.CSS_SELECTOR, '.agenda-link.filterable')
self.assertGreater(len(elements_to_check), 0, 'No elements with agenda links to update were found') self.assertGreater(len(elements_to_check), 0, 'No elements with agenda links to update were found')
self.assertFalse( self.assertFalse(
any(checkbox.is_selected() any(checkbox.is_selected()
for checkbox in self.driver.find_elements_by_css_selector( for checkbox in self.driver.find_elements(By.CSS_SELECTOR,
'input.checkbox[name="selected-sessions"]')), 'input.checkbox[name="selected-sessions"]')),
'Sessions were selected before being clicked', 'Sessions were selected before being clicked',
) )
mars_checkbox = self.driver.find_element_by_css_selector('input[type="checkbox"][name="selected-sessions"][data-filter-item="mars"]') mars_checkbox = self.driver.find_element(By.CSS_SELECTOR, 'input[type="checkbox"][name="selected-sessions"][data-filter-item="mars"]')
break_checkbox = self.driver.find_element_by_css_selector('input[type="checkbox"][name="selected-sessions"][data-filter-item="secretariat-sessb"]') break_checkbox = self.driver.find_element(By.CSS_SELECTOR, 'input[type="checkbox"][name="selected-sessions"][data-filter-item="secretariat-sessb"]')
registration_checkbox = self.driver.find_element_by_css_selector('input[type="checkbox"][name="selected-sessions"][data-filter-item="secretariat-sessa"]') registration_checkbox = self.driver.find_element(By.CSS_SELECTOR, 'input[type="checkbox"][name="selected-sessions"][data-filter-item="secretariat-sessa"]')
secretariat_button = self.driver.find_element_by_css_selector('button[data-filter-item="secretariat"]') secretariat_button = self.driver.find_element(By.CSS_SELECTOR, 'button[data-filter-item="secretariat"]')
mars_checkbox.click() # select mars session mars_checkbox.click() # select mars session
try: try:
@ -1868,9 +1868,9 @@ class WeekviewTests(IetfSeleniumTestCase):
def _assert_wrapped(displayed, expected_time_string): def _assert_wrapped(displayed, expected_time_string):
self.assertEqual(len(displayed), 2) self.assertEqual(len(displayed), 2)
first = displayed[0] first = displayed[0]
first_parent = first.find_element_by_xpath('..') first_parent = first.find_element(By.XPATH, '..')
second = displayed[1] second = displayed[1]
second_parent = second.find_element_by_xpath('..') second_parent = second.find_element(By.XPATH, '..')
self.assertNotIn('continued', first.text) self.assertNotIn('continued', first.text)
self.assertIn(expected_time_string, first_parent.text) self.assertIn(expected_time_string, first_parent.text)
self.assertIn('continued', second.text) self.assertIn('continued', second.text)
@ -1879,7 +1879,7 @@ class WeekviewTests(IetfSeleniumTestCase):
def _assert_not_wrapped(displayed, expected_time_string): def _assert_not_wrapped(displayed, expected_time_string):
self.assertEqual(len(displayed), 1) self.assertEqual(len(displayed), 1)
first = displayed[0] first = displayed[0]
first_parent = first.find_element_by_xpath('..') first_parent = first.find_element(By.XPATH, '..')
self.assertNotIn('continued', first.text) self.assertNotIn('continued', first.text)
self.assertIn(expected_time_string, first_parent.text) self.assertIn(expected_time_string, first_parent.text)
@ -2053,7 +2053,7 @@ class InterimTests(IetfSeleniumTestCase):
return meetings return meetings
def find_upcoming_meeting_entries(self): def find_upcoming_meeting_entries(self):
return self.driver.find_elements_by_css_selector( return self.driver.find_elements(By.CSS_SELECTOR,
'table#upcoming-meeting-table a.ietf-meeting-link, table#upcoming-meeting-table a.interim-meeting-link' 'table#upcoming-meeting-table a.ietf-meeting-link, table#upcoming-meeting-table a.interim-meeting-link'
) )
@ -2103,7 +2103,7 @@ class InterimTests(IetfSeleniumTestCase):
# 12 in order to check the starting month of the following year, which # 12 in order to check the starting month of the following year, which
# will usually contain the day 1 year from the start date. # will usually contain the day 1 year from the start date.
for _ in range(13): for _ in range(13):
entries = self.driver.find_elements_by_css_selector( entries = self.driver.find_elements(By.CSS_SELECTOR,
'div#calendar div.fc-content' 'div#calendar div.fc-content'
) )
for entry in entries: for entry in entries:
@ -2134,9 +2134,9 @@ class InterimTests(IetfSeleniumTestCase):
if simplified_querystring in ['?show=', '?hide=', '?show=&hide=']: if simplified_querystring in ['?show=', '?hide=', '?show=&hide=']:
simplified_querystring = '' # these empty querystrings will be dropped (not an exhaustive list) simplified_querystring = '' # these empty querystrings will be dropped (not an exhaustive list)
ics_link = self.driver.find_element_by_link_text('Download as .ics') ics_link = self.driver.find_element(By.LINK_TEXT, 'Download as .ics')
self.assertIn(simplified_querystring, ics_link.get_attribute('href')) self.assertIn(simplified_querystring, ics_link.get_attribute('href'))
webcal_link = self.driver.find_element_by_link_text('Subscribe with webcal') webcal_link = self.driver.find_element(By.LINK_TEXT, 'Subscribe with webcal')
self.assertIn(simplified_querystring, webcal_link.get_attribute('href')) self.assertIn(simplified_querystring, webcal_link.get_attribute('href'))
def assert_upcoming_view_filter_matches_ics_filter(self, filter_string): def assert_upcoming_view_filter_matches_ics_filter(self, filter_string):
@ -2298,8 +2298,8 @@ class InterimTests(IetfSeleniumTestCase):
ts = session.official_timeslotassignment().timeslot ts = session.official_timeslotassignment().timeslot
start = ts.utc_start_time().astimezone(zone).strftime('%Y-%m-%d %H:%M') start = ts.utc_start_time().astimezone(zone).strftime('%Y-%m-%d %H:%M')
end = ts.utc_end_time().astimezone(zone).strftime('%H:%M') end = ts.utc_end_time().astimezone(zone).strftime('%H:%M')
meeting_link = self.driver.find_element_by_link_text(session.meeting.number) meeting_link = self.driver.find_element(By.LINK_TEXT, session.meeting.number)
time_td = meeting_link.find_element_by_xpath('../../td[@class="session-time"]') time_td = meeting_link.find_element(By.XPATH, '../../td[@class="session-time"]')
self.assertIn('%s - %s' % (start, end), time_td.text) self.assertIn('%s - %s' % (start, end), time_td.text)
def _assert_ietf_tz_correct(meetings, tz): def _assert_ietf_tz_correct(meetings, tz):
@ -2317,8 +2317,8 @@ class InterimTests(IetfSeleniumTestCase):
start = start_dt.astimezone(zone).strftime('%Y-%m-%d') start = start_dt.astimezone(zone).strftime('%Y-%m-%d')
end = end_dt.astimezone(zone).strftime('%Y-%m-%d') end = end_dt.astimezone(zone).strftime('%Y-%m-%d')
meeting_link = self.driver.find_element_by_link_text("IETF " + meeting.number) meeting_link = self.driver.find_element(By.LINK_TEXT, "IETF " + meeting.number)
time_td = meeting_link.find_element_by_xpath('../../td[@class="meeting-time"]') time_td = meeting_link.find_element(By.XPATH, '../../td[@class="meeting-time"]')
self.assertIn('%s - %s' % (start, end), time_td.text) self.assertIn('%s - %s' % (start, end), time_td.text)
sessions = [m.session_set.first() for m in self.displayed_interims()] sessions = [m.session_set.first() for m in self.displayed_interims()]
@ -2327,12 +2327,12 @@ class InterimTests(IetfSeleniumTestCase):
self.assertGreater(len(ietf_meetings), 0) self.assertGreater(len(ietf_meetings), 0)
self.driver.get(self.absreverse('ietf.meeting.views.upcoming')) self.driver.get(self.absreverse('ietf.meeting.views.upcoming'))
tz_select_input = self.driver.find_element_by_id('timezone-select') tz_select_input = self.driver.find_element(By.ID, 'timezone-select')
tz_select_bottom_input = self.driver.find_element_by_id('timezone-select-bottom') tz_select_bottom_input = self.driver.find_element(By.ID, 'timezone-select-bottom')
local_tz_link = self.driver.find_element_by_id('local-timezone') local_tz_link = self.driver.find_element(By.ID, 'local-timezone')
utc_tz_link = self.driver.find_element_by_id('utc-timezone') utc_tz_link = self.driver.find_element(By.ID, 'utc-timezone')
local_tz_bottom_link = self.driver.find_element_by_id('local-timezone-bottom') local_tz_bottom_link = self.driver.find_element(By.ID, 'local-timezone-bottom')
utc_tz_bottom_link = self.driver.find_element_by_id('utc-timezone-bottom') utc_tz_bottom_link = self.driver.find_element(By.ID, 'utc-timezone-bottom')
# wait for the select box to be updated - look for an arbitrary time zone to be in # wait for the select box to be updated - look for an arbitrary time zone to be in
# its options list to detect this # its options list to detect this
@ -2342,18 +2342,18 @@ class InterimTests(IetfSeleniumTestCase):
(By.CSS_SELECTOR, '#timezone-select > option[value="%s"]' % arbitrary_tz) (By.CSS_SELECTOR, '#timezone-select > option[value="%s"]' % arbitrary_tz)
) )
) )
arbitrary_tz_bottom_opt = tz_select_bottom_input.find_element_by_css_selector( arbitrary_tz_bottom_opt = tz_select_bottom_input.find_element(By.CSS_SELECTOR,
'option[value="%s"]' % arbitrary_tz) 'option[value="%s"]' % arbitrary_tz)
utc_tz_opt = tz_select_input.find_element_by_css_selector('option[value="UTC"]') utc_tz_opt = tz_select_input.find_element(By.CSS_SELECTOR, 'option[value="UTC"]')
utc_tz_bottom_opt= tz_select_bottom_input.find_element_by_css_selector('option[value="UTC"]') utc_tz_bottom_opt= tz_select_bottom_input.find_element(By.CSS_SELECTOR, 'option[value="UTC"]')
# Moment.js guesses local time zone based on the behavior of Selenium's web client. This seems # Moment.js guesses local time zone based on the behavior of Selenium's web client. This seems
# to inherit Django's settings.TIME_ZONE but I don't know whether that's guaranteed to be consistent. # to inherit Django's settings.TIME_ZONE but I don't know whether that's guaranteed to be consistent.
# To avoid test fragility, ask Moment what it considers local and expect that. # To avoid test fragility, ask Moment what it considers local and expect that.
local_tz = self.driver.execute_script('return moment.tz.guess();') local_tz = self.driver.execute_script('return moment.tz.guess();')
local_tz_opt = tz_select_input.find_element_by_css_selector('option[value=%s]' % local_tz) local_tz_opt = tz_select_input.find_element(By.CSS_SELECTOR, 'option[value=%s]' % local_tz)
local_tz_bottom_opt = tz_select_bottom_input.find_element_by_css_selector('option[value="%s"]' % local_tz) local_tz_bottom_opt = tz_select_bottom_input.find_element(By.CSS_SELECTOR, 'option[value="%s"]' % local_tz)
# Should start off in local time zone # Should start off in local time zone
self.assertTrue(local_tz_opt.is_selected()) self.assertTrue(local_tz_opt.is_selected())
@ -2450,7 +2450,7 @@ class InterimTests(IetfSeleniumTestCase):
slug = assignment.slug() slug = assignment.slug()
# modal should start hidden # modal should start hidden
modal_div = self.driver.find_element_by_css_selector('div#modal-%s' % slug) modal_div = self.driver.find_element(By.CSS_SELECTOR, 'div#modal-%s' % slug)
self.assertFalse(modal_div.is_displayed()) self.assertFalse(modal_div.is_displayed())
# Click the 'materials' button # Click the 'materials' button
@ -2600,4 +2600,4 @@ class ProceedingsMaterialTests(IetfSeleniumTestCase):
# #
# def testOpenSchedule(self): # def testOpenSchedule(self):
# url = urlreverse('ietf.meeting.views.edit_schedule', kwargs=dict(num='72',name='test-schedule')) # url = urlreverse('ietf.meeting.views.edit_schedule', kwargs=dict(num='72',name='test-schedule'))
# r = self.client.get(url) # r = self.client.get(url)

View file

@ -8,7 +8,10 @@ skip_selenium = False
skip_message = "" skip_message = ""
try: try:
from selenium import webdriver 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.action_chains import ActionChains
from selenium.webdriver.common.by import By
except ImportError as e: except ImportError as e:
skip_selenium = True skip_selenium = True
skip_message = "Skipping selenium tests: %s" % e skip_message = "Skipping selenium tests: %s" % e
@ -18,7 +21,6 @@ from ietf.utils.pipe import pipe
from ietf.utils.test_runner import IetfLiveServerTestCase from ietf.utils.test_runner import IetfLiveServerTestCase
from ietf import settings from ietf import settings
executable_name = 'chromedriver' executable_name = 'chromedriver'
code, out, err = pipe('{} --version'.format(executable_name)) code, out, err = pipe('{} --version'.format(executable_name))
if code != 0: if code != 0:
@ -28,12 +30,15 @@ if skip_selenium:
print(" "+skip_message) print(" "+skip_message)
def start_web_driver(): def start_web_driver():
options = webdriver.ChromeOptions() service = Service(executable_path="chromedriver",
log_path=settings.TEST_GHOSTDRIVER_LOG_PATH)
service.start()
options = Options()
options.add_argument("headless") options.add_argument("headless")
options.add_argument("disable-extensions") options.add_argument("disable-extensions")
options.add_argument("disable-gpu") # headless needs this options.add_argument("disable-gpu") # headless needs this
options.add_argument("no-sandbox") # docker needs this options.add_argument("no-sandbox") # docker needs this
return webdriver.Chrome(options=options, service_log_path=settings.TEST_GHOSTDRIVER_LOG_PATH) return webdriver.Chrome(service=service, options=options)
def selenium_enabled(): def selenium_enabled():
@ -69,9 +74,9 @@ class IetfSeleniumTestCase(IetfLiveServerTestCase):
url = self.absreverse(self.login_view) url = self.absreverse(self.login_view)
password = '%s+password' % username password = '%s+password' % username
self.driver.get(url) self.driver.get(url)
self.driver.find_element_by_name('username').send_keys(username) self.driver.find_element(By.NAME, 'username').send_keys(username)
self.driver.find_element_by_name('password').send_keys(password) self.driver.find_element(By.NAME, 'password').send_keys(password)
self.driver.find_element_by_xpath('//button[@type="submit"]').click() self.driver.find_element(By.XPATH, '//button[@type="submit"]').click()
def scroll_to_element(self, element): def scroll_to_element(self, element):
"""Scroll an element into view""" """Scroll an element into view"""
@ -89,5 +94,5 @@ class presence_of_element_child_by_css_selector:
self.child_selector = child_selector self.child_selector = child_selector
def __call__(self, driver): def __call__(self, driver):
child = self.element.find_element_by_css_selector(self.child_selector) child = self.element.find_element(By.CSS_SELECTOR, self.child_selector)
return child if child is not None else False return child if child is not None else False