Exemplo n.º 1
0
    def submit_prepared_ballot(self, ballot):
        browser = self.browser
        timeout = settings.EXPLICIT_WAIT_TIMEOUT
        console_log("#### Going to election page")
        election_page_url = election_id_to_election_home_page_url(self.election_id)
        browser.get(election_page_url)

        console_log("#### Clicking on 'en' language link")
        election_home_page = ElectionHomePage(browser, timeout)
        election_home_page.click_on_language_link("en")

        console_log("#### Clicking on 'Advanced mode' link")
        election_home_page.click_on_advanced_mode_link()

        console_log("#### Filling ballot field with text representation of ballot and clicking on Submit button")
        field_css_selector = "form[action=submit-ballot] textarea[name=encrypted_vote]"
        field_element = wait_for_element_exists(browser, field_css_selector, timeout)
        field_element.clear()
        field_element.send_keys(ballot)
        field_element.submit()

        wait_a_bit()

        @try_several_times(5)
        def verify_page_title(browser):
            console_log("#### Analyzing contents of page returned after having clicked on Submit button, expecting title to be either 'Ill-formed ballot' or 'Password login'")
            page_title_css_selector = "#header h1"
            page_title_element = wait_for_element_exists(browser, page_title_css_selector)
            page_title_label = page_title_element.get_attribute('innerText') # Here we sometimes get a stale element. This is why we run this inside a loop with several attempts

            page_content_css_selector = "#main"
            page_content_element = wait_for_element_exists(browser, page_content_css_selector)
            page_content_label = page_content_element.get_attribute('innerText')

            console_log("#### Page title was", page_title_label, "and page content was", page_content_label)
            if page_title_label == "Error":
                assert page_content_label == "Ill-formed ballot"
                return page_title_label
            elif page_title_label == "Authenticate with password":
                return page_title_label
            else:
                # This case happens sometimes, because Selenium has not yet replaced its DOM with the new DOM of the page (maybe because server has not responded yet or page loading is not yet complete).
                # In this situation, data is still: ('Unexpected page content', 'USERNAME:\t\nPASSWORD:\t')
                # Or: ('Unexpected page content', 'My test election for Scenario 1', 'Username:Password:')
                raise Exception("Unexpected page content", page_title_label, page_content_label)

        try:
            page_title = verify_page_title(browser)
            assert page_title in ["Error", "Authenticate with password"]
            return page_title
        except Exception as e:
            console_log("Could not locate expected element. Exception received:", e)
            # browser.quit()
            # self.browser = initialize_browser()
            raise e
Exemplo n.º 2
0
    def one_voter_votes(self, voter, direct=False):
        browser = self.browser
        timeout = settings.EXPLICIT_WAIT_TIMEOUT

        if direct:
            browser.get(settings.SERVER_URL + "/vote.html#" +
                        urlencode({"uuid": self.election_id}))

        else:
            # Bob has received 2 emails containing an invitation to vote and all necessary credentials (election page URL, username, password). He goes to the election page URL.
            browser.get(voter["election_page_url"])

            wait_a_bit()

            # He clicks on "en" language
            election_home_page = ElectionHomePage(browser, timeout)
            election_home_page.click_on_language_link("en")

            # He clicks on the "Start" button
            election_home_page.click_on_start_button()

        wait_a_bit()

        # A loading screen appears, then another screen appears. He clicks on the "Here" button. A modal opens (it is an HTML modal created using Window.prompt()), with an input field. He types his credential.
        step_1_page = NormalVoteStep1Page(browser, timeout)
        step_1_page.verify_page()
        step_1_page.click_on_here_button_and_type_voter_credential(
            voter["credential"])

        wait_a_bit()

        # A new screen appears, which has a title "Step 2/6: Answer to questions", and a content:
        # "Question 1?"
        # "Question #1 of 1 — select between 1 and 2 answer(s)"
        # [ ] "Answer 1"
        # [ ] "Answer 2"
        # [Next]
        # (where "[ ]" is a checkbox, and [Next] is a button)
        step_2_page = NormalVoteStep2Page(browser, timeout)
        step_2_page.verify_page()

        # He fills his votes to each answer of the question
        vote_data = voter["votes"]
        step_2_page.fill_vote_form(vote_data)

        wait_a_bit()

        # He clicks on the "Next" button
        step_2_page.click_on_next_button()

        wait_a_bit()
        """
        A new screen appears, showing:

        Step 3/6: Review and encrypt
        Question 1?
        - Answer 1

        Your ballot has been successfully encrypted, but has not been cast yet!

        Your smart ballot tracker is sLRilXoAYcodIrjWrOqPrVXLNlRyCJAqFeeHZ4WCajU

        We invite you to save it in order to check later that it is taken into account.

        [Continue]
        [Restart]
        """
        step_3_page = NormalVoteStep3Page(browser, timeout)
        step_3_page.verify_page()
        # He remembers the smart ballot tracker that is displayed.
        smart_ballot_tracker_value = step_3_page.get_smart_ballot_tracker_value(
        )
        assert len(smart_ballot_tracker_value) > 5
        voter["smart_ballot_tracker"] = smart_ballot_tracker_value

        # He clicks on the "Continue" button
        step_3_page.click_on_continue_button()

        wait_a_bit()

        # He arrives on the login page, with a login form (as he has not already logged in during this visit, he does not arrive directly on the step 5 page)
        login_page = VoterLoginPage(browser, timeout)
        login_page.verify_page()

        # He types his voter username and password, and submits the form
        login_page.log_in(voter["username"], voter["password"])

        wait_a_bit()

        # He verifies that he is now on step 5 and that page content is correct (page contains 'has been received, but not recorded yet'; page contains a ballot tracker which is the same as the one he noted; page contains voter's username)
        step_5_page = NormalVoteStep5Page(browser, timeout)
        step_5_page.verify_page(smart_ballot_tracker_value, voter["username"])

        # He clicks on the "I cast my vote" button
        step_5_page.click_on_i_cast_my_vote_button()

        wait_a_bit()
Exemplo n.º 3
0
    def test_sometimes_smart_monkey_votes(self):
        console_log("# test_sometimes_smart_monkey_votes()")
        browser = self.browser
        timeout = settings.EXPLICIT_WAIT_TIMEOUT
        election_url = get_election_url(self.election_id)
        console_log("## Going to election page:", election_url)
        browser.get(election_url)

        wait_a_bit()

        console_log("## Starting clicker monkey behaviour")
        monkey = SeleniumClickerMonkey(browser, election_url, 0.25, belenios_fence_filter, verify_page_is_not_an_error_page)
        maximum_monkey_clicks = 50
        monkey.start(maximum_monkey_clicks)
        console_log("## End of clicker monkey behaviour")

        console_log("## Going to election page again", election_url)
        browser.get(election_url)

        wait_a_bit()

        console_log("## Clicking on 'en' language link")
        election_home_page = ElectionHomePage(browser, timeout)
        election_home_page.click_on_language_link("en")

        wait_a_bit()

        console_log("## Clicking on 'Start' button")
        election_home_page.click_on_start_button()

        wait_a_bit()

        console_log("## Verifying that we are on step 1 page")
        step_1_page = NormalVoteStep1Page(browser, timeout)
        step_1_page.verify_page()

        # Here:
        # We cannot have a monkey behaviour, because there is only one button to click (the "here" button).
        # We can go back. This goes back to election home page

        console_log("## Clicking on 'here' button")
        step_1_page.click_on_here_button_and_type_voter_credential(settings.VOTER_CREDENTIAL)

        wait_a_bit()

        step_2_page = NormalVoteStep2Page(browser, timeout)
        step_2_page.verify_page()

        # Here:
        # We can check any checkbox for the question (check 0 to n checkboxes)
        # We can click on the "Next" button
        # We can go back. This would go back to the election home page (not to the "Step 1" page, which would probably have been the intuitive behaviour)

        console_log("## Answering vote question by checking randomly some checkboxes")
        step_2_parent_css_selector = "#question_div"
        form_filler_monkey = SeleniumFormFillerMonkey(browser, step_2_parent_css_selector) # Warning: In the DOM of the vote page, step 2, checkboxes are not in a `<form>`.
        form_filler_monkey.fill_form()

        console_log("## Click on the 'Next' button")
        step_2_page.click_on_next_button()

        wait_a_bit()

        console_log("## Verify that we are on step 3 and that page content is correct (ballot tracker is not empty)")
        step_3_page = NormalVoteStep3Page(browser, timeout)
        step_3_page.verify_page()
        step_3_smart_ballot_tracker_value = step_3_page.get_smart_ballot_tracker_value()

        # Here:
        # We can click on the "Continue" button (`<input style="font-size:30px;" value="Continue" type="submit">`)
        # We can click on the "Restart" button (`<button onclick="location.reload();">Restart</button>`). This goes back to step 1.

        console_log("## Click on the 'Continue' button")
        step_3_page.click_on_continue_button()

        wait_a_bit()

        # We arrive on the login form (if we have not already logged in during this visit, which could happen if we do a complex navigation after a first login. If we have already logged in, we arrive directly on the step 5 page)
        console_log("## Verify that we are on login page")
        login_page = VoterLoginPage(browser, timeout)
        login_page.verify_page()

        # Here:
        # We can click on the "Login" button without filling the username nor password field
        # We can click on the "Login" button after having filled the username and password fields with wrong data
        # We can click on the "Login" button after having filled the username and password fields with correct data
        # We can go back. This goes back to step 3.

        # If we don't fill the form, or fill the form with wrong username/password, and click on the "Login" button, we arrive on an "Unauthorized" "Error 401" page.

        # If we fill the form with correct data and click on the "Login" button, we arrive on step 5 page.

        console_log("## Filling log in form and submitting it")
        login_page.log_in(settings.VOTER_USERNAME, settings.VOTER_PASSWORD)

        console_log("## Verify that we are on step 5 and that page content is correct (page contains 'has been received, but not recorded yet'; page contains a ballot tracker which is the same as the one we noted; page contains voter's username)")
        step_5_page = NormalVoteStep5Page(browser, timeout)
        step_5_page.verify_page(step_3_smart_ballot_tracker_value, settings.VOTER_USERNAME)

        # Here:
        # We can click on the Belenios logo on the top-left of the screen
        # We can click on a link in the footer
        # We can click on the "I cast my vote" button
        # We can click on the "Go back to election" link
        # We can go back. This goes back to the Login page which immediately redirects to this same step 5 page.

        console_log("Click on the 'I cast my vote' button")
        step_5_page.click_on_i_cast_my_vote_button()

        wait_a_bit()

        console_log("## Verify that we are on step 6 and that page content is correct (page contains 'has been accepted'; page contains a ballot tracker which is the same as the one we noted)")
        step_6_page = NormalVoteStep6Page(browser, timeout)
        step_6_page.verify_page(step_3_smart_ballot_tracker_value)

        # Here:
        # We can click on the Belenios logo on the top-left of the screen
        # We can click on a link in the footer
        # We can click on the "ballot box" link
        # We can click on the "Go back to election" link
        # We can go back. This goes to another page which looks like the "Advanced mode" page. This looks like a small bug.

        console_log("## Click on the 'ballot box' link")
        step_6_page.click_on_ballot_box_link()

        wait_a_bit()

        console_log("## Verify that ballot box page contains a link labelled as voter's smart ballot tracker, and click on it")
        ballot_box_page = BallotBoxPage(browser, timeout)
        ballot_box_page.verify_page(step_3_smart_ballot_tracker_value)
        ballot_box_page.click_on_ballot_link(step_3_smart_ballot_tracker_value)

        console_log("## Verify that my ballot page is not an error page")
        verify_page_is_not_an_error_page(browser)
Exemplo n.º 4
0
 def __init__(self, *args, **kwargs):
     super().__init__(*args, **kwargs)
     self.page = ElectionHomePage(self.browser, self.timeout)
Exemplo n.º 5
0
class ElectionHomePageState(StateForSmartMonkey):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.page = ElectionHomePage(self.browser, self.timeout)

    def click_on_start_button_generator(self):
        def click_on_start_button(in_memory=None):
            self.page.click_on_language_link(
                "en"
            )  # For the rest of the test, we need language to be English, because DOM selectors for links and buttons use English language
            self.page.click_on_start_button()
            return NormalVoteStep1PageState(self.browser, self.timeout,
                                            ElectionHomePageState)

        return click_on_start_button

    def get_all_possible_actions(self):
        def click_on_start_button(in_memory=None):
            self.page.click_on_language_link(
                "en"
            )  # For the rest of the test, we need language to be English, because DOM selectors for links and buttons use English language
            self.page.click_on_start_button()
            return NormalVoteStep1PageState(self.browser, self.timeout,
                                            ElectionHomePageState)

        def click_on_en_language_link(in_memory=None):
            self.page.click_on_language_link("en")
            return self

        def click_on_fr_language_link(in_memory=None):
            self.page.click_on_language_link("fr")
            return self

        def click_on_accept_personal_data_policy_link(in_memory=None):
            try:
                if self.browser.find_element_by_link_text("Accept"):
                    self.page.click_on_accept_personal_data_policy_link()
            finally:
                return self

        def click_on_advanced_mode_link(in_memory=None):
            self.page.click_on_advanced_mode_link()
            return AdvancedModeVotePageState(self.browser, self.timeout,
                                             ElectionHomePageState)

        def click_on_see_accepted_ballots_link(in_memory=None):
            self.page.click_on_see_accepted_ballots_link()
            return BallotBoxPageState(self.browser, self.timeout,
                                      ElectionHomePageState)

        return [
            click_on_start_button,
            click_on_en_language_link,
            click_on_fr_language_link,
            click_on_accept_personal_data_policy_link,
            click_on_advanced_mode_link,
            click_on_see_accepted_ballots_link,
        ]