def verify_that_we_are_on_step_6(browser, timeout): all_ballots_link_expected_label = "ballot box" all_ballots_element = wait_for_an_element_with_link_text_exists(browser, all_ballots_link_expected_label, timeout) current_step_css_selector = ".current_step" current_step_expected_content = "Step 6/6: Thank you for voting!" wait_for_element_exists_and_contains_expected_text(browser, current_step_css_selector, current_step_expected_content, timeout) return all_ballots_element
def administrator_finishes_tallying_of_election(self, max_trustees=None): self.browser = initialize_browser_for_scenario_2() browser = self.browser # Alice goes to the election page election_url = self.election_page_url browser.get(election_url) wait_a_bit() # She clicks on "en" language english_language_link_expected_label = "en" english_language_link_element = wait_for_an_element_with_link_text_exists( browser, english_language_link_expected_label, settings.EXPLICIT_WAIT_TIMEOUT) english_language_link_element.click() wait_a_bit() # She clicks on the "Administer this election" link administration_link_label = "Administer this election" administration_link_element = wait_for_an_element_with_partial_link_text_exists( browser, administration_link_label, settings.EXPLICIT_WAIT_TIMEOUT) administration_link_element.click() # She logs in as administrator log_in_as_administrator(browser, from_a_login_page=True) wait_a_bit() # She checks that the "DONE?" column of each trustee is to "Yes" (or if there is a threshold on trustees, she checks that at least `max_trustees` have a "Yes") expected_label = "Yes" yes_cells_selector = "#main table tr td:nth-last-child(1)" attribute_name = "innerText" if max_trustees is None: verify_all_elements_have_attribute_value(browser, yes_cells_selector, attribute_name, expected_label) else: verify_some_elements_have_attribute_value(browser, yes_cells_selector, attribute_name, expected_label, max_trustees) # She clicks on the "Compute the result" button compute_result_button_expected_label = "Compute the result" compute_result_button_css_selector = "#main input[type=submit][value='" + compute_result_button_expected_label + "']" compute_result_button_element = wait_for_element_exists( browser, compute_result_button_css_selector) compute_result_button_element.click() wait_a_bit() self.administrator_verifies_vote_results()
def administrator_does_tallying_of_election(self): browser = self.browser # Alice goes to the election page election_url = self.election_page_url # Could also be obtained with self.voters_data[self.voters_email_addresses[0]]["election_page_url"] browser.get(election_url) wait_a_bit() # She clicks on "en" language english_language_link_expected_label = "en" english_language_link_element = wait_for_an_element_with_link_text_exists( browser, english_language_link_expected_label, settings.EXPLICIT_WAIT_TIMEOUT) english_language_link_element.click() wait_a_bit() # She clicks on the "Administer this election" link administration_link_label = "Administer this election" administration_link_element = wait_for_an_element_with_partial_link_text_exists( browser, administration_link_label, settings.EXPLICIT_WAIT_TIMEOUT) administration_link_element.click() # She logs in as administrator log_in_as_administrator(browser, from_a_login_page=True) wait_a_bit() # She clicks on the "Close election" button close_election_button_label = "Close election" close_election_button_css_selector = build_css_selector_to_find_buttons_in_page_content_by_value( close_election_button_label) close_election_button_element = wait_for_element_exists( browser, close_election_button_css_selector, settings.EXPLICIT_WAIT_TIMEOUT) close_election_button_element.click() wait_a_bit() # She clicks on the "Proceed to vote counting" button proceed_button_label = "Proceed to vote counting" proceed_button_css_selector = build_css_selector_to_find_buttons_in_page_content_by_value( proceed_button_label) proceed_button_element = wait_for_element_exists( browser, proceed_button_css_selector, settings.EXPLICIT_WAIT_TIMEOUT) proceed_button_element.click() wait_a_bit() # FIXME: If no voter has cast their vote, it shows a "Internal Server Error" "Error 500" page self.administrator_verifies_vote_results()
def verify_step_5_and_6(browser, timeout): # Verify that page contains a ballot tracker smart_ballot_tracker_css_selector = "#ballot_tracker" smart_ballot_tracker_element = wait_for_element_exists_and_has_non_empty_content( browser, smart_ballot_tracker_css_selector, timeout) my_smart_ballot_tracker_value = smart_ballot_tracker_element.get_attribute( 'innerText') assert len(my_smart_ballot_tracker_value) > 5 # Click "I cast my vote" button submit_button_css_selector = "form input[type=submit]" submit_button_expected_content = "I cast my vote" verify_all_elements_have_attribute_value( browser, submit_button_css_selector, "value", submit_button_expected_content, timeout) submit_button_element = wait_for_element_exists( browser, submit_button_css_selector, timeout) submit_button_element.click() wait_a_bit() # Verify that vote has been accepted by the server @try_several_times(max_attempts=3) def verify_that_we_are_on_step_6(browser, timeout): all_ballots_link_expected_label = "ballot box" all_ballots_element = wait_for_an_element_with_link_text_exists( browser, all_ballots_link_expected_label, timeout) current_step_css_selector = ".current_step" current_step_expected_content = "Step 6/6: Thank you for voting!" wait_for_element_exists_and_contains_expected_text( browser, current_step_css_selector, current_step_expected_content, timeout) return all_ballots_element all_ballots_element = verify_that_we_are_on_step_6( browser, timeout) # Go to all ballots page all_ballots_element.click() wait_a_bit() # Verify presence of my ballot my_smart_ballot_tracker_link_element = wait_for_an_element_with_link_text_exists( browser, my_smart_ballot_tracker_value, settings.EXPLICIT_WAIT_TIMEOUT) my_smart_ballot_tracker_link_element.click()
def administrator_starts_tallying_of_election(self, with_threshold=None): browser = self.browser # Alice goes to the election page election_url = self.election_page_url # Could also be obtained with self.voters_data[self.voters_email_addresses[0]]["election_page_url"] browser.get(election_url) wait_a_bit() # She clicks on "en" language english_language_link_expected_label = "en" english_language_link_element = wait_for_an_element_with_link_text_exists( browser, english_language_link_expected_label, settings.EXPLICIT_WAIT_TIMEOUT) english_language_link_element.click() wait_a_bit() # She clicks on the "Administer this election" link administration_link_label = "Administer this election" administration_link_element = wait_for_an_element_with_partial_link_text_exists( browser, administration_link_label, settings.EXPLICIT_WAIT_TIMEOUT) administration_link_element.click() # She logs in as administrator log_in_as_administrator(browser, from_a_login_page=True) wait_a_bit() # She clicks on the "Close election" button close_election_button_label = "Close election" close_election_button_css_selector = build_css_selector_to_find_buttons_in_page_content_by_value( close_election_button_label) close_election_button_element = wait_for_element_exists( browser, close_election_button_css_selector, settings.EXPLICIT_WAIT_TIMEOUT) close_election_button_element.click() wait_a_bit() # She clicks on the "Proceed to vote counting" button proceed_button_label = "Proceed to vote counting" proceed_button_css_selector = build_css_selector_to_find_buttons_in_page_content_by_value( proceed_button_label) proceed_button_element = wait_for_element_exists( browser, proceed_button_css_selector, settings.EXPLICIT_WAIT_TIMEOUT) proceed_button_element.click() wait_a_bit() if with_threshold is not None: # She checks the presence of text "We are now waiting for trustees... At least ${U} trustee(s) must act." expected_confirmation_label = "We are now waiting for trustees... At least " + str( with_threshold) + " trustee(s) must act." expected_confirmation_css_selector = "#main" wait_for_element_exists_and_contains_expected_text( browser, expected_confirmation_css_selector, expected_confirmation_label) # She checks that in the table on every content row, the "DONE?" column is "No" elements_css_selector = "#main table tr td:nth-of-type(4)" attribute_name = "innerText" attribute_value = "No" verify_all_elements_have_attribute_value( browser, elements_css_selector, attribute_name, attribute_value, extractor=(lambda x: x[1:])) # She remembers the link to send to each trustee, so they can tally the election row_padding = 3 self.closed_election_tally_links_for_trustees = [] for idx, email_address in enumerate(settings.TRUSTEES_EMAIL_ADDRESSES): trustee_link_css_selector = "#main table tr:nth-of-type(" + str( idx + row_padding ) + ") td:nth-of-type(3) a" # First row consists in column titles. Second row is for server. trustee_link_element = wait_for_element_exists_and_has_non_empty_content( browser, trustee_link_css_selector) self.closed_election_tally_links_for_trustees.append( trustee_link_element.get_attribute('href')) # She sends to each trustee an email containing their own link subject = "Link to tally the election" content_format = """\ Dear trustee, The election is now closed. Here's the link to proceed to tally: {link_for_trustee} Here's the instructions: 1. Follow the link. 2. Enter your private decryption key in the first box and click on "generate decryption factors" 3. The second box is now filled with crypto material. Please press the button "submit". Thank you again for your help, -- The election administrator.\ """ for idx, trustee_email_address in enumerate( settings.TRUSTEES_EMAIL_ADDRESSES): custom_content = content_format.format( link_for_trustee=self. closed_election_tally_links_for_trustees[idx]) self.fake_sent_emails_manager.send_email( settings.ADMINISTRATOR_EMAIL_ADDRESS, trustee_email_address, subject, custom_content) # She logs out log_out(browser) # She closes the window browser.quit()
def verify_page(self): wait_for_an_element_exists_and_is_visible_and_contains_expected_text(self.browser, "h1", "Administration", self.timeout) wait_for_an_element_with_link_text_exists(self.browser, "Log out", self.timeout)
def click_on_link_with_expected_label(self, expected_label): link_element = wait_for_an_element_with_link_text_exists(self.browser, expected_label, self.timeout) link_element.click()
def cast_all_votes_from_csv(self): browser = self.browser generated_files_destination_folder = settings.GENERATED_FILES_DESTINATION_FOLDER csv_file_path = os.path.join(generated_files_destination_folder, 'all_votes.csv') with open(csv_file_path, 'r', newline='') as csvfile: csvreader = csv.DictReader(csvfile, delimiter=',', quotechar='|') current_row = 0 for row in csvreader: current_row += 1 if current_row <= settings.SKIP_ROWS_IN_CSV_FILE: continue voter_email_address = row['voter_email_address'] voter_password = row['voter_password'] voter_encrypted_ballot_file_name = row[ 'voter_encrypted_ballot_file_name'] election_page_url = row['election_page_url'] with ConsoleLogDuration( f"Row {current_row} (voter {voter_email_address})"): # Go to election home browser.get(election_page_url) wait_a_bit() # She clicks on "en" language select = Select( wait_for_element_exists( browser, ".lang_box select", settings.EXPLICIT_WAIT_TIMEOUT)) select.select_by_visible_text("en") submit = wait_for_element_exists( browser, ".lang_box input[type=submit]", settings.EXPLICIT_WAIT_TIMEOUT) submit.click() wait_a_bit() # Click on advanced mode advanced_mode_link_expected_label = "Advanced mode" advanced_mode_link_element = wait_for_an_element_with_link_text_exists( browser, advanced_mode_link_expected_label, settings.EXPLICIT_WAIT_TIMEOUT) advanced_mode_link_element.click() wait_a_bit() # Browse file and submit it browse_button_css_selector = "form input[name=encrypted_vote][type=file]" browse_button_element = wait_for_element_exists( browser, browse_button_css_selector) path_of_file_to_upload = os.path.join( generated_files_destination_folder, voter_encrypted_ballot_file_name) browse_button_element.clear() browse_button_element.send_keys(path_of_file_to_upload) browse_button_element.submit() wait_a_bit() # Submit login form username_field_css_selector = "form input[name=username]" username_field_element = wait_for_element_exists( browser, username_field_css_selector) username_field_element.clear() username_field_element.send_keys(voter_email_address) password_field_css_selector = "form input[name=password]" password_field_element = wait_for_element_exists( browser, password_field_css_selector) password_field_element.clear() password_field_element.send_keys(voter_password) password_field_element.submit() wait_a_bit() @try_several_times(max_attempts=3) def verify_step_5_and_6(browser, timeout): # Verify that page contains a ballot tracker smart_ballot_tracker_css_selector = "#ballot_tracker" smart_ballot_tracker_element = wait_for_element_exists_and_has_non_empty_content( browser, smart_ballot_tracker_css_selector, timeout) my_smart_ballot_tracker_value = smart_ballot_tracker_element.get_attribute( 'innerText') assert len(my_smart_ballot_tracker_value) > 5 # Click "I cast my vote" button submit_button_css_selector = "form input[type=submit]" submit_button_expected_content = "I cast my vote" verify_all_elements_have_attribute_value( browser, submit_button_css_selector, "value", submit_button_expected_content, timeout) submit_button_element = wait_for_element_exists( browser, submit_button_css_selector, timeout) submit_button_element.click() wait_a_bit() # Verify that vote has been accepted by the server @try_several_times(max_attempts=3) def verify_that_we_are_on_step_6(browser, timeout): all_ballots_link_expected_label = "ballot box" all_ballots_element = wait_for_an_element_with_link_text_exists( browser, all_ballots_link_expected_label, timeout) current_step_css_selector = ".current_step" current_step_expected_content = "Step 6/6: Thank you for voting!" wait_for_element_exists_and_contains_expected_text( browser, current_step_css_selector, current_step_expected_content, timeout) return all_ballots_element all_ballots_element = verify_that_we_are_on_step_6( browser, timeout) # Go to all ballots page all_ballots_element.click() wait_a_bit() # Verify presence of my ballot my_smart_ballot_tracker_link_element = wait_for_an_element_with_link_text_exists( browser, my_smart_ballot_tracker_value, settings.EXPLICIT_WAIT_TIMEOUT) my_smart_ballot_tracker_link_element.click() timeout = settings.EXPLICIT_WAIT_TIMEOUT verify_step_5_and_6(browser, timeout)