def test_submit_prepared_ballot_by_smart_monkey_v2(self, ballot): try: browser = self.browser timeout = settings.EXPLICIT_WAIT_TIMEOUT ballot['election_uuid'] = self.election_id printable_ballot = json.dumps(ballot) console_log("### Starting a new Monkey navigation that will try to submit ballot:", printable_ballot) result = self.submit_prepared_ballot(printable_ballot) if result: console_log("#### Page title was 'Password login', so we log in") # Our ballot is not detected as ill-formed, so we arrive on the log in screen console_log("#### Verify that we are on login page") login_page = VoterLoginPage(browser, timeout) login_page.verify_page() console_log("#### Filling log in form and submitting it") login_page.log_in(settings.VOTER_USERNAME, settings.VOTER_PASSWORD) console_log("#### Analyzing page title, expecting it not to be 'Unauthorized'") # If user provided a wrong username/password combination, the resulting page is a browser error page like `<h1>Unauthorized</h1><p>Error 401</p>` page_title_css_selector = "h1" expected_text_1 = "Authenticate with password" expected_text_2 = "Unauthorized" page_title_element = wait_for_element_exists_and_does_not_contain_expected_text(browser, page_title_css_selector, expected_text_1, timeout) page_title_element = wait_for_element_exists_and_does_not_contain_expected_text(browser, page_title_css_selector, expected_text_2, timeout) page_title_label = page_title_element.get_attribute('innerText') assert page_title_label != expected_text_1 assert page_title_label != expected_text_2 console_log("#### Page title was not 'Unauthorized', so we click on confirm ballot submission button") # We arrive on the next screen, which asks us to confirm ballot submission submit_button_css_selector = "input[type=submit]" submit_button_element = wait_for_element_exists(browser, submit_button_css_selector, timeout) submit_button_element.click() # We check wether the ballot has been received and parsed without errors @try_several_times(5) def verify_step_label(browser, current_attempt=0): console_log("#### Analyzing (attempt", current_attempt, ") whether result page (after click on confirm ballot submission button) has as step title 'Step 6/6: FAIL!' because ballot content is invalid") current_step_css_selector = "#main .current_step" current_step_element = wait_for_element_exists(browser, current_step_css_selector, timeout) current_step_label = current_step_element.get_attribute('innerText') console_log("#### Step title is:", current_step_label) if current_step_label == "Step 6/6: FAIL!": console_log("#### Page step title was 'Step 6/6: FAIL!', which is what we expected. So the full test is correct.") return current_step_label else: # Possibility of improvement: Handle very improbable case where Belenios server accepts the ballot because by chance this ballot generated by Hypothesis would be correct. For now we consider that if Belenios accepts the generated ballot (correct or incorrect), it is a test failure. Maybe also it could be necessary to better detect any case that falls outside these 2 situations. console_log("#### Step title is unexpected. So the full test is incorrect.") raise Exception("Step title is unexpected:", current_step_label) final_label = verify_step_label(browser) assert final_label == "Step 6/6: FAIL!" except Exception as e: console_log("Step title is unexpected. Exception received:", e) browser.quit() self.browser = initialize_browser() raise e
def setUp(self): self.fake_sent_emails_manager = FakeSentEmailsManager(settings.SENT_EMAILS_TEXT_FILE_ABSOLUTE_PATH) self.fake_sent_emails_manager.install_fake_sendmail_log_file() if settings.START_SERVER: if settings.CLEAN_UP_POLICY == settings.CLEAN_UP_POLICIES.REMOVE_DATABASE: remove_database_folder() elif settings.CLEAN_UP_POLICY == settings.CLEAN_UP_POLICIES.REMOVE_ELECTION or settings.CLEAN_UP_POLICY == settings.CLEAN_UP_POLICIES.DO_NOTHING: pass self.server = initialize_server() self.browser = initialize_browser() if settings.ELECTION_ID: self.election_id = settings.ELECTION_ID else: # Download server's sent emails text file, so that we know up to which line number we have to ignore its contents (this is its last line) temporary_fake_sent_emails_manager = None try: temporary_fake_sent_emails_manager = self.download_all_sent_emails() self.fake_sent_emails_initial_lines_count = temporary_fake_sent_emails_manager.count_lines() console_log("### Initial lines count of server's fake sent emails file:", self.fake_sent_emails_initial_lines_count) finally: if temporary_fake_sent_emails_manager: temporary_fake_sent_emails_manager.uninstall_fake_sendmail_log_file() self.administrator_creates_election() console_log("### Starting step: download_all_sent_emails") self.distant_fake_sent_emails_manager = self.download_all_sent_emails() console_log("### Step complete: download_all_sent_emails") # Concatenate (distant) Belenios server's sent emails file (starting after line `fake_sent_emails_initial_lines_count`) and local credential authority's sent emails file into file `self.distant_fake_sent_emails_manager.log_file_path`, so that `self.generate_vote_ballots()` can parse it and find all information it needs. import subprocess import tempfile (file_handle, log_file_path) = tempfile.mkstemp(text=True) with open(log_file_path, 'w') as f: subprocess.run(["tail", "-n", "+" + str(self.fake_sent_emails_initial_lines_count + 1), self.distant_fake_sent_emails_manager.log_file_path], stdout=f) subprocess.run(["cat", self.fake_sent_emails_manager.log_file_path], stdout=f) subprocess.run(["cp", log_file_path, self.distant_fake_sent_emails_manager.log_file_path]) subprocess.run(["rm", "-f", log_file_path]) invited_voters_who_will_vote = random.sample(self.voters_email_addresses, settings.NUMBER_OF_VOTING_VOTERS) invited_voters_who_will_vote_data = populate_credential_and_password_for_voters_from_sent_emails(self.distant_fake_sent_emails_manager, invited_voters_who_will_vote, settings.ELECTION_TITLE) invited_voters_who_will_vote_data = populate_random_votes_for_voters(invited_voters_who_will_vote_data) self.update_voters_data(invited_voters_who_will_vote_data) selected_voter = invited_voters_who_will_vote_data[0] settings.VOTER_USERNAME = selected_voter["username"] settings.VOTER_PASSWORD = selected_voter["password"] settings.VOTER_CREDENTIAL = selected_voter["credential"] console_log("Going to vote using VOTER_USERNAME:"******"Going to vote using VOTER_PASSWORD:"******"Going to vote using VOTER_CREDENTIAL:", settings.VOTER_CREDENTIAL)