mirror of
https://github.com/GSA/notifications-admin.git
synced 2026-08-24 16:24:08 -04:00
Clean up state of E2E tests
This changeset takes care of leaving E2E tests in a clean state so that we can revisit the work later. The efforts to add authentication support did not pan out, so we will go a different route in the near future. Signed-off-by: Carlo Costino <carlo.costino@gsa.gov>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import copy
|
||||
import json
|
||||
import os
|
||||
import re
|
||||
from contextlib import contextmanager
|
||||
from datetime import date, datetime, timedelta
|
||||
from unittest.mock import Mock, PropertyMock
|
||||
@@ -3347,13 +3348,94 @@ def mock_get_invited_org_user_by_id(mocker, sample_org_invite):
|
||||
)
|
||||
|
||||
|
||||
def login_for_end_to_end_testing(browser):
|
||||
# Open a new page and go to the staging site.
|
||||
context = browser.new_context()
|
||||
page = context.new_page()
|
||||
page.goto(os.getenv('NOTIFY_E2E_TEST_URI'))
|
||||
|
||||
sign_in_button = page.get_by_role('link', name='Sign in')
|
||||
|
||||
# Test trying to sign in.
|
||||
sign_in_button.click()
|
||||
|
||||
# Wait for the next page to fully load.
|
||||
page.wait_for_load_state('domcontentloaded')
|
||||
|
||||
# Check for the sign in form elements.
|
||||
# NOTE: Playwright cannot find input elements by role and recommends using
|
||||
# get_by_label() instead; however, hidden form elements do not have
|
||||
# labels associated with them, hence the XPath!
|
||||
# See https://playwright.dev/python/docs/api/class-page#page-get-by-label
|
||||
# and https://playwright.dev/python/docs/locators#locate-by-css-or-xpath
|
||||
# for more information.
|
||||
email_address_input = page.get_by_label('Email address')
|
||||
password_input = page.get_by_label('Password')
|
||||
continue_button = page.get_by_role('button', name=re.compile('Continue'))
|
||||
|
||||
# Sign in to the site.
|
||||
email_address_input.fill(os.getenv('NOTIFY_E2E_TEST_EMAIL'))
|
||||
password_input.fill(os.getenv('NOTIFY_E2E_TEST_PASSWORD'))
|
||||
continue_button.click()
|
||||
|
||||
# Wait for the next page to fully load.
|
||||
page.wait_for_load_state('domcontentloaded')
|
||||
|
||||
# Check for the sign in form elements.
|
||||
# NOTE: Playwright cannot find input elements by role and recommends using
|
||||
# get_by_label() instead; however, hidden form elements do not have
|
||||
# labels associated with them, hence the XPath!
|
||||
# See https://playwright.dev/python/docs/api/class-page#page-get-by-label
|
||||
# and https://playwright.dev/python/docs/locators#locate-by-css-or-xpath
|
||||
# for more information.
|
||||
# mfa_input = page.get_by_label('Text message code')
|
||||
# continue_button = page.get_by_role('button', name=re.compile('Continue'))
|
||||
|
||||
# # Enter MFA code and continue.
|
||||
# TODO: Revisit this at a later point in time.
|
||||
# totp = pyotp.TOTP(
|
||||
# os.getenv('MFA_TOTP_SECRET'),
|
||||
# digits=int(os.getenv('MFA_TOTP_LENGTH'))
|
||||
# )
|
||||
|
||||
# mfa_input.fill(totp.now())
|
||||
# continue_button.click()
|
||||
|
||||
# page.wait_for_load_state('domcontentloaded')
|
||||
|
||||
# # Save storage state into the file.
|
||||
# auth_state_path = os.path.join(
|
||||
# os.getenv('NOTIFY_E2E_AUTH_STATE_PATH'),
|
||||
# 'state.json'
|
||||
# )
|
||||
# context.storage_state(path=auth_state_path)
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def end_to_end_auth_context(browser):
|
||||
def end_to_end_context(browser):
|
||||
# Create a context with HTTP Authentication credentials for Playwright E2E
|
||||
# tests.
|
||||
context = browser.new_context(http_credentials={
|
||||
'username': os.environ.get('NOTIFY_STAGING_HTTP_AUTH_USER'),
|
||||
'password': os.environ.get('NOTIFY_STAGING_HTTP_AUTH_PASSWORD'),
|
||||
})
|
||||
# tests, if the environment variables exist.
|
||||
if os.getenv('NOTIFY_E2E_TEST_HTTP_AUTH_USER'):
|
||||
context = browser.new_context(http_credentials={
|
||||
'username': os.getenv('NOTIFY_E2E_TEST_HTTP_AUTH_USER'),
|
||||
'password': os.getenv('NOTIFY_E2E_TEST_HTTP_AUTH_PASSWORD'),
|
||||
})
|
||||
else:
|
||||
context = browser.new_context()
|
||||
|
||||
yield context
|
||||
|
||||
|
||||
@pytest.fixture(scope='session')
|
||||
def end_to_end_authenticated_context(browser):
|
||||
# Create and load a previously authenticated context for Playwright E2E
|
||||
# tests.
|
||||
login_for_end_to_end_testing(browser)
|
||||
|
||||
auth_state_path = os.path.join(
|
||||
os.getenv('NOTIFY_E2E_AUTH_STATE_PATH'),
|
||||
'state.json'
|
||||
)
|
||||
context = browser.new_context(storage_state=auth_state_path)
|
||||
|
||||
yield context
|
||||
|
||||
122
tests/end_to_end/test_accounts_page.py
Normal file
122
tests/end_to_end/test_accounts_page.py
Normal file
@@ -0,0 +1,122 @@
|
||||
import datetime
|
||||
import os
|
||||
import re
|
||||
|
||||
import pytest
|
||||
from playwright.sync_api import expect
|
||||
|
||||
|
||||
@pytest.mark.skip(reason='Not authenticating test users.')
|
||||
def test_accounts_page(end_to_end_authenticated_context):
|
||||
# Open a new page and go to the staging site.
|
||||
page = end_to_end_authenticated_context.new_page()
|
||||
|
||||
accounts_uri = '{}accounts'.format(os.getenv('NOTIFY_E2E_TEST_URI'))
|
||||
|
||||
page.goto(accounts_uri)
|
||||
|
||||
# Check to make sure that we've arrived at the next page.
|
||||
page.wait_for_load_state('domcontentloaded')
|
||||
|
||||
# Check to make sure that we've arrived at the next page.
|
||||
# Check the page title exists and matches what we expect.
|
||||
expect(page).to_have_title(re.compile('Choose service'))
|
||||
|
||||
# Check for the sign in heading.
|
||||
sign_in_heading = page.get_by_role('heading', name='Choose service')
|
||||
expect(sign_in_heading).to_be_visible()
|
||||
|
||||
# Retrieve some prominent elements on the page for testing.
|
||||
add_service_button = page.get_by_role(
|
||||
'button',
|
||||
name=re.compile('Add a new service')
|
||||
)
|
||||
|
||||
expect(add_service_button).to_be_visible()
|
||||
|
||||
|
||||
@pytest.mark.skip(reason='Not authenticating test users.')
|
||||
def test_add_new_service_workflow(end_to_end_authenticated_context):
|
||||
# Prepare for adding a new service later in the test.
|
||||
current_date_time = datetime.datetime.now()
|
||||
new_service_name = 'E2E Federal Test Service {now} - {browser_type}'.format(
|
||||
now=current_date_time.strftime('%m/%d/%Y %H:%M:%S'),
|
||||
browser_type=end_to_end_authenticated_context.browser.browser_type.name
|
||||
)
|
||||
|
||||
# Open a new page and go to the staging site.
|
||||
page = end_to_end_authenticated_context.new_page()
|
||||
|
||||
accounts_uri = '{}accounts'.format(os.getenv('NOTIFY_E2E_TEST_URI'))
|
||||
|
||||
page.goto(accounts_uri)
|
||||
|
||||
# Check to make sure that we've arrived at the next page.
|
||||
page.wait_for_load_state('domcontentloaded')
|
||||
|
||||
# Check to make sure that we've arrived at the next page.
|
||||
# Check the page title exists and matches what we expect.
|
||||
expect(page).to_have_title(re.compile('Choose service'))
|
||||
|
||||
# Check for the sign in heading.
|
||||
sign_in_heading = page.get_by_role('heading', name='Choose service')
|
||||
expect(sign_in_heading).to_be_visible()
|
||||
|
||||
# Retrieve some prominent elements on the page for testing.
|
||||
add_service_button = page.get_by_role(
|
||||
'button',
|
||||
name=re.compile('Add a new service')
|
||||
)
|
||||
|
||||
expect(add_service_button).to_be_visible()
|
||||
|
||||
existing_service_link = page.get_by_role(
|
||||
'link',
|
||||
name=new_service_name
|
||||
)
|
||||
|
||||
# Check to see if the service was already created - if so, we should fail.
|
||||
# TODO: Figure out how to make this truly isolated, and/or work in a
|
||||
# delete service workflow.
|
||||
expect(existing_service_link).to_have_count(0)
|
||||
|
||||
# Click on add a new service.
|
||||
add_service_button.click()
|
||||
|
||||
# Check to make sure that we've arrived at the next page.
|
||||
page.wait_for_load_state('domcontentloaded')
|
||||
|
||||
# Check for the sign in heading.
|
||||
about_heading = page.get_by_role('heading', name='About your service')
|
||||
expect(about_heading).to_be_visible()
|
||||
|
||||
# Retrieve some prominent elements on the page for testing.
|
||||
service_name_input = page.locator('xpath=//input[@name="name"]')
|
||||
federal_radio_button = page.locator('xpath=//input[@value="federal"]')
|
||||
state_radio_button = page.locator('xpath=//input[@value="state"]')
|
||||
other_radio_button = page.locator('xpath=//input[@value="other"]')
|
||||
add_service_button = page.get_by_role(
|
||||
'button',
|
||||
name=re.compile('Add service')
|
||||
)
|
||||
|
||||
expect(service_name_input).to_be_visible()
|
||||
expect(federal_radio_button).to_be_visible()
|
||||
expect(state_radio_button).to_be_visible()
|
||||
expect(other_radio_button).to_be_visible()
|
||||
expect(add_service_button).to_be_visible()
|
||||
|
||||
# Fill in the form.
|
||||
service_name_input.fill(new_service_name)
|
||||
federal_radio_button.click()
|
||||
|
||||
# Click on add service.
|
||||
add_service_button.click()
|
||||
|
||||
# Check to make sure that we've arrived at the next page.
|
||||
page.wait_for_load_state('domcontentloaded')
|
||||
|
||||
# Check for the service name title and heading.
|
||||
service_heading = page.get_by_text(new_service_name)
|
||||
expect(service_heading).to_be_visible()
|
||||
expect(page).to_have_title(re.compile(new_service_name))
|
||||
@@ -1,13 +1,17 @@
|
||||
import os
|
||||
import re
|
||||
|
||||
import pytest
|
||||
from playwright.sync_api import expect
|
||||
|
||||
|
||||
def test_landing_page(end_to_end_auth_context):
|
||||
def test_landing_page(end_to_end_context):
|
||||
# Open a new page and go to the staging site.
|
||||
page = end_to_end_auth_context.new_page()
|
||||
page.goto(os.environ.get('NOTIFY_STAGING_URI'))
|
||||
page = end_to_end_context.new_page()
|
||||
page.goto(os.getenv('NOTIFY_E2E_TEST_URI'))
|
||||
|
||||
# Check to make sure that we've arrived at the next page.
|
||||
page.wait_for_load_state('domcontentloaded')
|
||||
|
||||
# Check the page title exists and matches what we expect.
|
||||
expect(page).to_have_title(re.compile('Notify.gov'))
|
||||
@@ -50,22 +54,22 @@ def test_landing_page(end_to_end_auth_context):
|
||||
).to_be_visible()
|
||||
|
||||
|
||||
def test_sign_in_page(end_to_end_auth_context):
|
||||
@pytest.mark.skip(reason='Not authenticating test users.')
|
||||
def test_sign_in_and_mfa_pages(end_to_end_context):
|
||||
# Open a new page and go to the staging site.
|
||||
page = end_to_end_auth_context.new_page()
|
||||
page.goto(os.environ.get('NOTIFY_STAGING_URI'))
|
||||
page = end_to_end_context.new_page()
|
||||
page.goto(os.getenv('NOTIFY_E2E_TEST_URI'))
|
||||
|
||||
sign_in_button = page.get_by_role('link', name='Sign in')
|
||||
|
||||
# Test trying to sign in.
|
||||
sign_in_button.click()
|
||||
|
||||
# Check to make sure that we've arrived at the next page.
|
||||
page.wait_for_load_state('domcontentloaded')
|
||||
|
||||
# Check the page title exists and matches what we expect.
|
||||
# NOTE: The dash is a special character! It had to be copied from
|
||||
# the template itself.
|
||||
# TODO: Improve this check, or change it so no special character is
|
||||
# needed. Better yet, fix the template(s) character too.
|
||||
expect(page).to_have_title(re.compile('Sign in – Notify.gov'))
|
||||
expect(page).to_have_title(re.compile('Sign in'))
|
||||
|
||||
# Check for the sign in heading.
|
||||
sign_in_heading = page.get_by_role('heading', name='Sign in')
|
||||
@@ -81,7 +85,10 @@ def test_sign_in_page(end_to_end_auth_context):
|
||||
email_address_input = page.get_by_label('Email address')
|
||||
password_input = page.get_by_label('Password')
|
||||
csrf_token = page.locator('xpath=//input[@name="csrf_token"]')
|
||||
continue_button = page.get_by_role('button', name=re.compile('Continue'))
|
||||
continue_button = page.get_by_role(
|
||||
'button',
|
||||
name=re.compile('Continue')
|
||||
)
|
||||
forgot_password_link = page.get_by_role(
|
||||
'link',
|
||||
name='Forgot your password?'
|
||||
@@ -106,4 +113,80 @@ def test_sign_in_page(end_to_end_auth_context):
|
||||
'/forgot-password'
|
||||
)
|
||||
|
||||
# TODO: Figure out how to actually sign in...
|
||||
# Sign in to the site.
|
||||
email_address_input.fill(
|
||||
os.getenv('NOTIFY_E2E_TEST_EMAIL')
|
||||
)
|
||||
password_input.fill(os.getenv('NOTIFY_E2E_TEST_PASSWORD'))
|
||||
continue_button.click()
|
||||
|
||||
# Wait for the next page to fully load.
|
||||
page.wait_for_load_state('domcontentloaded')
|
||||
|
||||
# Check the page title exists and matches what we expect.
|
||||
expect(page).to_have_title(re.compile('Check your phone'))
|
||||
|
||||
# Check for the sign in heading.
|
||||
sign_in_heading = page.get_by_role(
|
||||
'heading',
|
||||
name='Check your phone'
|
||||
)
|
||||
expect(sign_in_heading).to_be_visible()
|
||||
|
||||
# Check for the sign in form elements.
|
||||
# NOTE: Playwright cannot find input elements by role and recommends using
|
||||
# get_by_label() instead; however, hidden form elements do not have
|
||||
# labels associated with them, hence the XPath!
|
||||
# See https://playwright.dev/python/docs/api/class-page#page-get-by-label
|
||||
# and https://playwright.dev/python/docs/locators#locate-by-css-or-xpath
|
||||
# for more information.
|
||||
mfa_input = page.get_by_label('Text message code')
|
||||
csrf_token = page.locator('xpath=//input[@name="csrf_token"]')
|
||||
continue_button = page.get_by_role(
|
||||
'button',
|
||||
name=re.compile('Continue')
|
||||
)
|
||||
not_received_message_link = page.get_by_role(
|
||||
'link',
|
||||
name='Not received a text message?'
|
||||
)
|
||||
|
||||
# Make sure form elements are visible and not visible as expected.
|
||||
expect(mfa_input).to_be_visible()
|
||||
expect(continue_button).to_be_visible()
|
||||
expect(not_received_message_link).to_be_visible()
|
||||
|
||||
expect(csrf_token).to_be_hidden()
|
||||
|
||||
# Make sure form elements are configured correctly with the right
|
||||
# attributes.
|
||||
expect(mfa_input).to_have_attribute('type', 'tel')
|
||||
expect(mfa_input).to_have_attribute('pattern', '[0-9]*')
|
||||
expect(csrf_token).to_have_attribute('type', 'hidden')
|
||||
expect(continue_button).to_have_attribute('type', 'submit')
|
||||
expect(not_received_message_link).to_have_attribute(
|
||||
'href',
|
||||
'/text-not-received'
|
||||
)
|
||||
|
||||
# Enter MFA code and continue.
|
||||
# TODO: Revisit this at a later point in time.
|
||||
# totp = pyotp.TOTP(
|
||||
# os.getenv('MFA_TOTP_SECRET'),
|
||||
# digits=int(os.getenv('MFA_TOTP_LENGTH'))
|
||||
# )
|
||||
|
||||
# mfa_input.fill('totp.now()')
|
||||
# continue_button.click()
|
||||
|
||||
# # Check to make sure that we've arrived at the next page.
|
||||
# page.wait_for_load_state('domcontentloaded')
|
||||
|
||||
# # Check that no MFA code error happened.
|
||||
# code_not_found_error = page.get_by_text('Code not found')
|
||||
# expect(code_not_found_error).to_have_count(0)
|
||||
|
||||
# # Check the page title exists and matches what we expect.
|
||||
# # This could be either the Dashboard of a service if there is only
|
||||
# # one, or choosing a service if there are multiple.
|
||||
# expect(page).to_have_title(re.compile('Dashboard|Choose service'))
|
||||
|
||||
Reference in New Issue
Block a user