Example #1
0
    def administrator_starts_creation_of_manual_election(self):
        # # Setting up a new election (action of the administrator)

        browser = self.browser

        # Alice has been given administrator rights on an online voting app called Belenios. She goes
        # to check out its homepage and logs in
        log_in_as_administrator(browser)

        # She starts creation of the election:
        # - She clicks on the "Prepare a new election" link
        # - She picks the Credential management method: manual
        # (- She keeps default value for Authentication method: it is Password, not CAS)
        # - She clicks on the "Proceed" button (this redirects to the "Preparation of election" page)
        # - In the "Name and description of the election" section, she changes values of fields name and description of the election
        # - She clicks on the "Save changes button" (the one that is next to the election description field)
        # - In "Contact" section, she changes the value of "contact" field
        # - She clicks on the "Save changes" button (the one that is in the "Contact" section)
        administrator_starts_creation_of_election(browser, True)

        # She remembers the URL of the draft election administration page
        self.draft_election_administration_page_url = browser.current_url

        # She edits election's questions:
        # - She clicks on the "Edit questions" link, to write her own questions
        # - She arrives on the Questions page. She checks that the page title is correct
        # - She removes answer 3
        # - She clicks on the "Save changes" button (this redirects to the "Preparation of election" page)
        administrator_edits_election_questions(browser)

        # She sets election's voters:
        # - She clicks on the "Edit voters" link, to then type the list of voters
        # - She types N e-mail addresses (the list of invited voters)
        # - She clicks on the "Add" button to submit changes
        # - She clicks on "Return to draft page" link
        self.voters_email_addresses = random_email_addresses_generator(
            settings.NUMBER_OF_INVITED_VOTERS)
        administrator_sets_election_voters(browser,
                                           self.voters_email_addresses)

        # In "Authentication" section, she clicks on the "Generate and mail missing passwords" button
        generate_and_mail_missing_passwords_button_label = "Generate and mail missing passwords"
        generate_and_mail_missing_passwords_button_css_selector = "#main input[type=submit][value='" + generate_and_mail_missing_passwords_button_label + "']"
        generate_and_mail_missing_passwords_button_element = wait_for_element_exists(
            browser, generate_and_mail_missing_passwords_button_css_selector,
            settings.EXPLICIT_WAIT_TIMEOUT)
        generate_and_mail_missing_passwords_button_element.click(
        )  # FIXME: This click does not get triggered when we have maximized the browser window

        wait_a_bit()

        # She checks that the page contains expected confirmation text, instead of an error (TODO: explain in which case an error can happen, and check that it does not show)
        confirmation_sentence_expected_text = "Passwords have been generated and mailed!"
        confirmation_sentence_css_selector = "#main p"
        wait_for_element_exists_and_contains_expected_text(
            browser, confirmation_sentence_css_selector,
            confirmation_sentence_expected_text,
            settings.EXPLICIT_WAIT_TIMEOUT)

        # She clicks on the "Proceed" link (this redirects to the "Preparation of election" page)
        proceed_link_expected_label = "Proceed"
        proceed_link_css_selector = "#main a"
        proceed_link_element = wait_for_element_exists_and_contains_expected_text(
            browser, proceed_link_css_selector, proceed_link_expected_label,
            settings.EXPLICIT_WAIT_TIMEOUT)
        proceed_link_element.click()

        wait_a_bit()

        # In "Credentials" section, she clicks on "Credential management" link
        credential_management_expected_label = "Credential management"
        credential_management_link_element = wait_for_an_element_with_partial_link_text_exists(
            browser, credential_management_expected_label)
        credential_management_link_element.click()

        wait_a_bit()

        # She fills in her public name, then clicks on "Set"
        credential_authority_css_selector = "#main form input[name=__co_eliom_name]"
        credential_authority_element = wait_for_element_exists(
            browser, credential_authority_css_selector,
            settings.EXPLICIT_WAIT_TIMEOUT)
        credential_authority_element.clear()
        credential_authority_element.send_keys("Cecily")
        credential_authority_set_css_selector = "#main form input[type=submit]"
        credential_authority_set_element = browser.find_element_by_css_selector(
            credential_authority_set_css_selector)
        credential_authority_set_element.click()

        wait_a_bit()

        # She clicks on the "Proceed" link
        proceed_link_expected_label = "Proceed"
        proceed_link_css_selector = "#main a"
        proceed_link_element = wait_for_element_exists_and_contains_expected_text(
            browser, proceed_link_css_selector, proceed_link_expected_label,
            settings.EXPLICIT_WAIT_TIMEOUT)
        proceed_link_element.click()

        wait_a_bit()

        # She remembers the link displayed
        link_for_credential_authority_css_selector = "#credential_authority_link"
        link_for_credential_authority_element = wait_for_element_exists_and_has_non_empty_content(
            browser, link_for_credential_authority_css_selector)
        link_label = link_for_credential_authority_element.get_attribute(
            'innerText').strip()
        self.credential_authority_link = link_label

        # She sends the remembered link to the credential authority by email (actually we don't need to send anything because we will act as the credential authority)

        # Optionnaly, she logs out
        # log_out(browser)

        # She closes the browser window
        browser.quit()
    def administrator_creates_election(self, nh_question=False):
        # # Setting up a new election (action of the administrator)

        browser = self.browser

        # Alice has been given administrator rights on an online voting app called Belenios. She goes
        # to check out its homepage and logs in
        log_in_as_administrator(browser)

        # She starts creation of the election:
        # - She clicks on the "Prepare a new election" link
        # (- She keeps default values on the form: Credential management is automatic (not manual), and Authentication method is Password, not CAS)
        # - She clicks on the "Proceed" button (this redirects to the "Preparation of election" page)
        # - She changes values of fields name and description of the election
        # - She clicks on the "Save changes button" (the one that is next to the election description field)
        administrator_starts_creation_of_election(browser)

        # She edits election's questions:
        # - She clicks on the "Edit questions" link, to write her own questions
        # - She arrives on the Questions page. She checks that the page title is correct
        # - She removes answer 3
        # - She clicks on the "Save changes" button (this redirects to the "Preparation of election" page)
        administrator_edits_election_questions(browser, nh_question)

        # She sets election's voters:
        # - She clicks on the "Edit voters" link, to then type the list of voters
        # - She types N e-mail addresses (the list of invited voters)
        # - She clicks on the "Add" button to submit changes
        # - She clicks on "Go back to election draft" link
        self.voters_email_addresses = random_email_addresses_generator(
            settings.NUMBER_OF_INVITED_VOTERS)
        administrator_sets_election_voters(browser,
                                           self.voters_email_addresses)

        # She clicks on button "Generate on server"
        generate_on_server_button_label = "Generate on server"
        generate_on_server_button_css_selector = build_css_selector_to_find_buttons_in_page_content_by_value(
            generate_on_server_button_label)
        generate_on_server_button_element = wait_for_element_exists(
            browser, generate_on_server_button_css_selector,
            settings.EXPLICIT_WAIT_TIMEOUT)
        generate_on_server_button_element.click()

        wait_a_bit()

        # (Server sends emails to voters.) She checks that server does not show any error that would happen when trying to send these emails (this can happen if sendmail is not configured)
        confirmation_sentence_expected_text = "Credentials have been generated and mailed!"
        confirmation_sentence_css_selector = "#main p"
        wait_for_element_exists_and_contains_expected_text(
            browser, confirmation_sentence_css_selector,
            confirmation_sentence_expected_text,
            settings.EXPLICIT_WAIT_TIMEOUT)

        # Now we do a sanity check that server has really tried to send emails. For this, we look for email addresses in the temporary file where our fake sendmail executable redirects its inputs to.
        """
        An email sent by Belenios (using sendmail or using the fake sendmail) to a voter looks like this:

Content-type: text/plain; charset="UTF-8"
Content-transfer-encoding: quoted-printable
From: Belenios public server <*****@*****.**>
To: "*****@*****.**"
 <*****@*****.**>
Subject: Your credential for election My test election for Scenario 1
MIME-Version: 1.0
X-Mailer: OcamlNet (ocamlnet.sourceforge.net)
Date: Wed, 31 Oct 2018 15:22:27 +0100

You are listed as a voter for the election

  My test election for Scenario 1

You will find below your credential.  To cast a vote, you will also
need a password, sent in a separate email.  Be careful, passwords and
credentials look similar but play different roles.  You will be asked
to enter your credential before entering the voting booth.  Login and
passwords are required once your ballot is ready to be cast.

Credential: yQVDQaKSAQVjdZq
Page of the election: http://localhost:8001/elections/AFFNDEPnpy21bw/

Note that you are allowed to vote several times.  Only the last vote
counts.

----------

Vous =C3=AAtes enregistr=C3=A9(e) en tant qu=27=C3=A9lecteur(trice) pour=20=
l=27=C3=A9lection

  My test election for Scenario 1

Veuillez trouver ci-dessous votre code de vote. Pour soumettre un
bulletin, vous aurez =C3=A9galement besoin d=27un mot de passe, envoy=C3=A9=
 dans
un e-mail s=C3=A9par=C3=A9. Soyez attentif(ve), le mot de passe et le cod=
e de
vote se ressemblent mais jouent des r=C3=B4les diff=C3=A9rents. Le syst=C3=
=A8me vous
demandera votre code de vote d=C3=A8s l=27entr=C3=A9e dans l=27isoloir=20=
virtuel. Le
nom d=27utilisateur et le mot de passe sont n=C3=A9cessaires lorsque votr=
e
bulletin est pr=C3=AAt =C3=A0 =C3=AAtre soumis.

Code de vote=C2=A0: yQVDQaKSAQVjdZq
Page de l=27=C3=A9lection=C2=A0: http://localhost:8001/elections/AFFNDEPn=
py21bw/

Notez que vous pouvez voter plusieurs fois. Seul le dernier vote est
pris en compte.

--=20
        """

        email_address_to_look_for = self.voters_email_addresses[0]
        text_to_look_for = 'To: "' + email_address_to_look_for + '"'
        email_address_found = self.fake_sent_emails_manager.find_in_sent_emails(
            text_to_look_for)
        assert email_address_found, "Text '" + email_address_to_look_for + "' not found in fake sendmail log file " + self.fake_sent_emails_manager.log_file_path

        # She clicks on the "Proceed" link
        proceed_link_css_selector = "#generic_proceed_link"
        proceed_link_element = wait_for_element_exists(
            browser, proceed_link_css_selector, settings.EXPLICIT_WAIT_TIMEOUT)
        proceed_link_element.click()

        wait_a_bit()

        # In "Authentication" section, she clicks on the "Generate and mail missing passwords" button
        generate_and_mail_missing_passwords_button_label = "Generate and mail missing passwords"
        generate_and_mail_missing_passwords_button_element = wait_for_element_exists(
            browser,
            build_css_selector_to_find_buttons_in_page_content_by_value(
                generate_and_mail_missing_passwords_button_label),
            settings.EXPLICIT_WAIT_TIMEOUT)
        generate_and_mail_missing_passwords_button_element.click()

        wait_a_bit()

        # She checks that the page contains expected confirmation text, instead of an error (TODO: explain in which case an error can happen, and check that it does not show)
        confirmation_sentence_expected_text = "Passwords have been generated and mailed!"
        confirmation_sentence_css_selector = "#main p"
        wait_for_element_exists_and_contains_expected_text(
            browser, confirmation_sentence_css_selector,
            confirmation_sentence_expected_text,
            settings.EXPLICIT_WAIT_TIMEOUT)

        # She clicks on the "Proceed" link (this redirects to the "Preparation of election" page)
        proceed_link_css_selector = "#generic_proceed_link"
        proceed_link_element = wait_for_element_exists(
            browser, proceed_link_css_selector, settings.EXPLICIT_WAIT_TIMEOUT)
        proceed_link_element.click()

        wait_a_bit()

        self.election_page_url = administrator_validates_creation_of_election(
            browser)
        console_log("election_page_url:", self.election_page_url)
        self.election_id = election_page_url_to_election_id(
            self.election_page_url)
        console_log("election_id:", self.election_id)

        log_out(browser, self.election_id)
Example #3
0
    def administrator_starts_creation_of_manual_election(self):
        # # Setting up a new election (action of the administrator)

        browser = self.browser

        # Alice has been given administrator rights on an online voting app called Belenios. She goes
        # to check out its homepage and logs in
        log_in_as_administrator(browser)

        # She starts creation of the election:
        # - She clicks on the "Prepare a new election" link
        # - She picks the Credential management method: manual
        # (- She keeps default value for Authentication method: it is Password, not CAS)
        # - She clicks on the "Proceed" button (this redirects to the "Preparation of election" page)
        # - She changes values of fields name and description of the election
        # - She clicks on the "Save changes button" (the one that is next to the election description field)
        administrator_starts_creation_of_election(browser, True)

        # She remembers the URL of the draft election administration page
        self.draft_election_administration_page_url = browser.current_url

        # She edits election's questions:
        # - She clicks on the "Edit questions" link, to write her own questions
        # - She arrives on the Questions page. She checks that the page title is correct
        # - She removes answer 3
        # - She clicks on the "Save changes" button (this redirects to the "Preparation of election" page)
        administrator_edits_election_questions(browser)

        # She sets election's voters:
        # - She clicks on the "Edit voters" link, to then type the list of voters
        # - She types N e-mail addresses (the list of invited voters)
        # - She clicks on the "Add" button to submit changes
        # - She clicks on "Return to draft page" link
        self.voters_email_addresses = random_email_addresses_generator(settings.NUMBER_OF_INVITED_VOTERS)
        administrator_sets_election_voters(browser, self.voters_email_addresses)

        # In "Authentication" section, she clicks on the "Generate and mail missing passwords" button
        generate_and_mail_missing_passwords_button_label = "Generate and mail missing passwords"
        generate_and_mail_missing_passwords_button_css_selector = "#main input[type=submit][value='" + generate_and_mail_missing_passwords_button_label + "']"
        generate_and_mail_missing_passwords_button_element = wait_for_element_exists(browser, generate_and_mail_missing_passwords_button_css_selector, settings.EXPLICIT_WAIT_TIMEOUT)
        generate_and_mail_missing_passwords_button_element.click() # FIXME: This click does not get triggered when we have maximized the browser window

        wait_a_bit()

        # She checks that the page contains expected confirmation text, instead of an error (TODO: explain in which case an error can happen, and check that it does not show)
        confirmation_sentence_expected_text = "Passwords have been generated and mailed!"
        confirmation_sentence_css_selector = "#main p"
        wait_for_element_exists_and_contains_expected_text(browser, confirmation_sentence_css_selector, confirmation_sentence_expected_text, settings.EXPLICIT_WAIT_TIMEOUT)

        # She clicks on the "Proceed" link (this redirects to the "Preparation of election" page)
        proceed_link_expected_label = "Proceed"
        proceed_link_css_selector = "#main a"
        proceed_link_element = wait_for_element_exists_and_contains_expected_text(browser, proceed_link_css_selector, proceed_link_expected_label, settings.EXPLICIT_WAIT_TIMEOUT)
        proceed_link_element.click()

        wait_a_bit()

        # In "Credentials" section, she clicks on "Credential management" link
        credential_management_expected_label = "Credential management"
        credential_management_link_element = wait_for_an_element_with_partial_link_text_exists(browser, credential_management_expected_label)
        credential_management_link_element.click()

        wait_a_bit()

        # She remembers the link displayed
        link_for_credential_authority_css_selector = "#main a"
        link_for_credential_authority_element = wait_for_element_exists_and_has_non_empty_content(browser, link_for_credential_authority_css_selector)
        link_label = link_for_credential_authority_element.get_attribute('innerText').strip()
        self.credential_authority_link = link_label

        # She sends the remembered link to the credential authority by email (actually we don't need to send anything because we will act as the credential authority)

        # Optionnaly, she logs out
        # log_out(browser)

        # She closes the browser window
        browser.quit()
Example #4
0
    def administrator_creates_election(self):
        # # Setting up a new election (action of the administrator)

        browser = self.browser

        # Alice has been given administrator rights on an online voting app called Belenios. She goes
        # to check out its homepage and logs in
        log_in_as_administrator(browser)

        # She starts creation of the election:
        # - She clicks on the "Prepare a new election" link
        # (- She keeps default values on the form: Credential management is automatic (not manual), and Authentication method is Password, not CAS)
        # - She clicks on the "Proceed" button (this redirects to the "Preparation of election" page)
        # - She changes values of fields name and description of the election
        # - She clicks on the "Save changes button" (the one that is next to the election description field)
        administrator_starts_creation_of_election(browser)

        # She edits election's questions:
        # - She clicks on the "Edit questions" link, to write her own questions
        # - She arrives on the Questions page. She checks that the page title is correct
        # - She removes answer 3
        # - She clicks on the "Save changes" button (this redirects to the "Preparation of election" page)
        administrator_edits_election_questions(browser)

        # She sets election's voters:
        # - She clicks on the "Edit voters" link, to then type the list of voters
        # - She types N e-mail addresses (the list of invited voters)
        # - She clicks on the "Add" button to submit changes
        # - She clicks on "Return to draft page" link
        self.voters_email_addresses = random_email_addresses_generator(settings.NUMBER_OF_INVITED_VOTERS)
        administrator_sets_election_voters(browser, self.voters_email_addresses)

        # She clicks on button "Generate on server"
        generate_on_server_button_label = "Generate on server"
        generate_on_server_button_css_selector = build_css_selector_to_find_buttons_in_page_content_by_value(generate_on_server_button_label)
        generate_on_server_button_element = wait_for_element_exists(browser, generate_on_server_button_css_selector, settings.EXPLICIT_WAIT_TIMEOUT)
        generate_on_server_button_element.click()

        wait_a_bit()

        # (Server sends emails to voters.) She checks that server does not show any error that would happen when trying to send these emails (this can happen if sendmail is not configured)
        confirmation_sentence_expected_text = "Credentials have been generated and mailed!"
        confirmation_sentence_css_selector = "#main p"
        wait_for_element_exists_and_contains_expected_text(browser, confirmation_sentence_css_selector, confirmation_sentence_expected_text, settings.EXPLICIT_WAIT_TIMEOUT)

        # Now we do a sanity check that server has really tried to send emails. For this, we look for email addresses in the temporary file where our fake sendmail executable redirects its inputs to.

        """
        An email sent by Belenios (using sendmail or using the fake sendmail) to a voter looks like this:

Content-type: text/plain; charset="UTF-8"
Content-transfer-encoding: quoted-printable
From: Belenios public server <*****@*****.**>
To: "*****@*****.**"
 <*****@*****.**>
Subject: Your credential for election My test election for Scenario 1
MIME-Version: 1.0
X-Mailer: OcamlNet (ocamlnet.sourceforge.net)
Date: Wed, 31 Oct 2018 15:22:27 +0100

You are listed as a voter for the election

  My test election for Scenario 1

You will find below your credential.  To cast a vote, you will also
need a password, sent in a separate email.  Be careful, passwords and
credentials look similar but play different roles.  You will be asked
to enter your credential before entering the voting booth.  Login and
passwords are required once your ballot is ready to be cast.

Credential: yQVDQaKSAQVjdZq
Page of the election: http://localhost:8001/elections/AFFNDEPnpy21bw/

Note that you are allowed to vote several times.  Only the last vote
counts.

----------

Vous =C3=AAtes enregistr=C3=A9(e) en tant qu=27=C3=A9lecteur(trice) pour=20=
l=27=C3=A9lection

  My test election for Scenario 1

Veuillez trouver ci-dessous votre code de vote. Pour soumettre un
bulletin, vous aurez =C3=A9galement besoin d=27un mot de passe, envoy=C3=A9=
 dans
un e-mail s=C3=A9par=C3=A9. Soyez attentif(ve), le mot de passe et le cod=
e de
vote se ressemblent mais jouent des r=C3=B4les diff=C3=A9rents. Le syst=C3=
=A8me vous
demandera votre code de vote d=C3=A8s l=27entr=C3=A9e dans l=27isoloir=20=
virtuel. Le
nom d=27utilisateur et le mot de passe sont n=C3=A9cessaires lorsque votr=
e
bulletin est pr=C3=AAt =C3=A0 =C3=AAtre soumis.

Code de vote=C2=A0: yQVDQaKSAQVjdZq
Page de l=27=C3=A9lection=C2=A0: http://localhost:8001/elections/AFFNDEPn=
py21bw/

Notez que vous pouvez voter plusieurs fois. Seul le dernier vote est
pris en compte.

--=20
        """

        email_address_to_look_for = self.voters_email_addresses[0]
        text_to_look_for = 'To: "' + email_address_to_look_for + '"'
        email_address_found = self.fake_sent_emails_manager.find_in_sent_emails(text_to_look_for)
        assert email_address_found, "Text '" + email_address_to_look_for + "'' not found in fake sendmail log file"


        # She clicks on the "Proceed" link
        proceed_link_css_selector = "#generic_proceed_link"
        proceed_link_element = wait_for_element_exists(browser, proceed_link_css_selector, settings.EXPLICIT_WAIT_TIMEOUT)
        proceed_link_element.click()

        wait_a_bit()

        # In "Authentication" section, she clicks on the "Generate and mail missing passwords" button
        generate_and_mail_missing_passwords_button_label = "Generate and mail missing passwords"
        generate_and_mail_missing_passwords_button_element = wait_for_element_exists(browser, build_css_selector_to_find_buttons_in_page_content_by_value(generate_and_mail_missing_passwords_button_label), settings.EXPLICIT_WAIT_TIMEOUT)
        generate_and_mail_missing_passwords_button_element.click()

        wait_a_bit()

        # She checks that the page contains expected confirmation text, instead of an error (TODO: explain in which case an error can happen, and check that it does not show)
        confirmation_sentence_expected_text = "Passwords have been generated and mailed!"
        confirmation_sentence_css_selector = "#main p"
        wait_for_element_exists_and_contains_expected_text(browser, confirmation_sentence_css_selector, confirmation_sentence_expected_text, settings.EXPLICIT_WAIT_TIMEOUT)

        # She clicks on the "Proceed" link (this redirects to the "Preparation of election" page)
        proceed_link_css_selector = "#generic_proceed_link"
        proceed_link_element = wait_for_element_exists(browser, proceed_link_css_selector, settings.EXPLICIT_WAIT_TIMEOUT)
        proceed_link_element.click()

        wait_a_bit()

        self.election_page_url = administrator_validates_creation_of_election(browser)
        console_log("election_page_url:", self.election_page_url)
        self.election_id = election_page_url_to_election_id(self.election_page_url)
        console_log("election_id:", self.election_id)

        log_out(browser)