Merge branch 'main' into 1169-display-confirmation-summary-on-the-preview-page

This commit is contained in:
Beverly Nguyen
2024-03-08 12:34:44 -08:00
57 changed files with 789 additions and 592 deletions

View File

@@ -160,8 +160,8 @@ def test_can_show_notifications(
assert normalize_spaces(
first_row.select_one(".table-field-right-aligned .align-with-message-body").text
) in [
"Delivered 1 January at 02:00 US/Eastern",
"Delivered 1 January at 01:00 US/Eastern",
"Delivered 01-01-2020 at 01:00 AM",
"Delivered 01-01-2020 at 01:00 AM",
]
assert page_title in page.h1.text.strip()
@@ -656,36 +656,36 @@ def test_redacts_templates_that_should_be_redacted(
@pytest.mark.parametrize(
("message_type", "status", "expected_hint_status", "single_line"),
[
("email", "created", "Sending since 27 September at 08:30 US/Eastern", True),
("email", "sending", "Sending since 27 September at 08:30 US/Eastern", True),
("email", "created", "Sending since 09-27-2017 at 08:30 AM", True),
("email", "sending", "Sending since 09-27-2017 at 08:30 AM", True),
(
"email",
"temporary-failure",
"Inbox not accepting messages right now 27 September at 08:30 US/Eastern",
"Inbox not accepting messages right now 09-27-2017 at 08:30 AM",
False,
),
(
"email",
"permanent-failure",
"Email address does not exist 27 September at 08:30 US/Eastern",
"Email address does not exist 09-27-2017 at 08:30 AM",
False,
),
("email", "delivered", "Delivered 27 September at 08:30 US/Eastern", True),
("sms", "created", "Sending since 27 September at 08:30 US/Eastern", True),
("sms", "sending", "Sending since 27 September at 08:30 US/Eastern", True),
("email", "delivered", "Delivered 09-27-2017 at 08:30 AM", True),
("sms", "created", "Sending since 09-27-2017 at 08:30 AM", True),
("sms", "sending", "Sending since 09-27-2017 at 08:30 AM", True),
(
"sms",
"temporary-failure",
"Phone not accepting messages right now 27 September at 08:30 US/Eastern",
"Phone not accepting messages right now 09-27-2017 at 08:30 AM",
False,
),
(
"sms",
"permanent-failure",
"Not delivered 27 September at 08:30 US/Eastern",
"Not delivered 09-27-2017 at 08:30 AM",
False,
),
("sms", "delivered", "Delivered 27 September at 08:30 US/Eastern", True),
("sms", "delivered", "Delivered 09-27-2017 at 08:30 AM", True),
],
)
def test_sending_status_hint_displays_correctly_on_notifications_page(

View File

@@ -90,7 +90,6 @@ def test_hiding_pages_from_search_engines(
[
"privacy",
"pricing",
"terms",
"roadmap",
"features",
"documentation",
@@ -167,7 +166,6 @@ def test_guidance_pages_link_to_service_pages_when_signed_in(
("information_risk_management", "security"),
("old_integration_testing", "integration_testing"),
("old_roadmap", "roadmap"),
("old_terms", "terms"),
("information_security", "using_notify"),
("old_using_notify", "using_notify"),
("delivery_and_failure", "message_status"),
@@ -226,12 +224,12 @@ def test_old_using_notify_page(client_request):
# )
def test_terms_page_has_correct_content(client_request):
terms_page = client_request.get("main.terms")
assert normalize_spaces(terms_page.select("main p")[0].text) == (
"These terms apply to your services use of Notify.gov. "
"You must be the service manager to accept them."
)
# def test_terms_page_has_correct_content(client_request):
# terms_page = client_request.get("main.terms")
# assert normalize_spaces(terms_page.select("main p")[0].text) == (
# "These terms apply to your services use of Notify.gov. "
# "You must be the service manager to accept them."
# )
def test_css_is_served_from_correct_path(client_request):

View File

@@ -90,7 +90,7 @@ def test_should_show_page_for_one_job(
assert page.h1.text.strip() == "thisisatest.csv"
assert " ".join(page.find("tbody").find("tr").text.split()) == (
"2021234567 template content Delivered 1 January at 06:09 US/Eastern"
"2021234567 template content Delivered 01-01-2016 at 06:09 AM"
)
assert page.find("div", {"data-key": "notifications"})["data-resource"] == url_for(
"main.view_job_updates",
@@ -109,7 +109,7 @@ def test_should_show_page_for_one_job(
assert page.find("span", {"id": "time-left"}).text == "Data available for 7 days"
assert normalize_spaces(page.select_one("tbody tr").text) == normalize_spaces(
"2021234567 " "template content " "Delivered 1 January at 06:09 US/Eastern"
"2021234567 " "template content " "Delivered 01-01-2016 at 06:09 AM"
)
assert page.select_one("tbody tr a")["href"] == url_for(
"main.view_notification",
@@ -424,8 +424,8 @@ def test_should_show_updates_for_one_job_as_json(
assert "2021234567" in content["notifications"]
assert "Status" in content["notifications"]
assert "Delivered" in content["notifications"]
assert "00:00" in content["notifications"]
assert "Sent by Test User on 1 January at 00:00" in content["status"]
assert "Sent by Test User on 01-01-2016 at 12:00 AM" in content["status"]
assert "12:00" in content["notifications"]
@freeze_time("2016-01-01 05:00:00.000001")
@@ -466,8 +466,8 @@ def test_should_show_updates_for_scheduled_job_as_json(
assert "2021234567" in content["notifications"]
assert "Status" in content["notifications"]
assert "Delivered" in content["notifications"]
assert "00:00" in content["notifications"]
assert "Sent by Test User on 1 June at 16:00" in content["status"]
assert "Sent by Test User on 06-01-2016 at 04:00 PM" in content["status"]
assert "12:00" in content["notifications"]
@pytest.mark.parametrize(

View File

@@ -862,9 +862,9 @@ def test_should_show_page_if_prefilled_user_is_already_invited(
mock_get_invites_for_service,
platform_admin_user,
):
active_user_with_permission_to_other_service[
"email_address"
] = "user_1@testnotify.gsa.gov"
active_user_with_permission_to_other_service["email_address"] = (
"user_1@testnotify.gsa.gov"
)
client_request.login(platform_admin_user)
mocker.patch(
"app.models.user.user_api_client.get_user",

View File

@@ -21,6 +21,9 @@ def test_render_sign_in_template_for_new_user(client_request):
# Removing for the pilot
# assert page.select('main a')[0].text == 'create one now'
# assert page.select('main a')[0]['href'] == url_for('main.register')
# TODO: Fix this test to be less brittle! If the Login.gov link is enabled,
# then these indices need to be 1 instead of 0.
# Currently it's not enabled for the test or production environments.
assert page.select("main a")[0].text == "Forgot your password?"
assert page.select("main a")[0]["href"] == url_for("main.forgot_password")
assert "Sign in again" not in normalize_spaces(page.text)

View File

@@ -31,9 +31,11 @@ def _folder(name, folder_id=None, parent=None, users_with_permission=None):
"name": name,
"id": folder_id or str(uuid.uuid4()),
"parent_id": parent,
"users_with_permission": users_with_permission
if users_with_permission is not None
else [sample_uuid()],
"users_with_permission": (
users_with_permission
if users_with_permission is not None
else [sample_uuid()]
),
}

View File

@@ -128,7 +128,6 @@ EXCLUDED_ENDPOINTS = tuple(
"old_integration_testing",
"old_roadmap",
"old_service_dashboard",
"old_terms",
"old_using_notify",
"organization_billing",
"organization_dashboard",
@@ -207,7 +206,6 @@ EXCLUDED_ENDPOINTS = tuple(
"suspend_service",
"template_history",
"template_usage",
"terms",
"tour_step",
"trial_mode",
"trial_mode_new",

View File

@@ -1,7 +1,6 @@
import copy
import json
import os
import re
from contextlib import contextmanager
from datetime import date, datetime, timedelta
from unittest.mock import Mock, PropertyMock
@@ -529,7 +528,7 @@ def mock_update_service(mocker):
"sms_sender",
"permissions",
]
}
},
)
return {"data": service}
@@ -905,9 +904,11 @@ def create_service_templates(service_id, number_of_templates=4):
"{}_template_{}".format(template_type, template_number),
template_type,
"{} template {} content".format(template_type, template_number),
subject="{} template {} subject".format(template_type, template_number)
if template_type == "email"
else None,
subject=(
"{} template {} subject".format(template_type, template_number)
if template_type == "email"
else None
),
)
)
@@ -1102,9 +1103,9 @@ def active_user_with_permission_to_other_service(
active_user_with_permission_to_two_services["permissions"].pop(SERVICE_ONE_ID)
active_user_with_permission_to_two_services["services"].pop(0)
active_user_with_permission_to_two_services["name"] = "Service Two User"
active_user_with_permission_to_two_services[
"email_address"
] = "service-two-user@test.gsa.gov"
active_user_with_permission_to_two_services["email_address"] = (
"service-two-user@test.gsa.gov"
)
return active_user_with_permission_to_two_services
@@ -2353,7 +2354,7 @@ def client_request(logged_in_client, mocker, service_one): # noqa (C901 too com
_test_page_title=True,
_test_for_elements_without_class=True,
_optional_args="",
**endpoint_kwargs
**endpoint_kwargs,
):
return ClientRequest.get_url(
url_for(endpoint, **(endpoint_kwargs or {})) + _optional_args,
@@ -2372,7 +2373,7 @@ def client_request(logged_in_client, mocker, service_one): # noqa (C901 too com
_expected_redirect=None,
_test_page_title=True,
_test_for_elements_without_class=True,
**endpoint_kwargs
**endpoint_kwargs,
):
resp = logged_in_client.get(
url,
@@ -2414,7 +2415,7 @@ def client_request(logged_in_client, mocker, service_one): # noqa (C901 too com
_follow_redirects=False,
_expected_redirect=None,
_content_type=None,
**endpoint_kwargs
**endpoint_kwargs,
):
return ClientRequest.post_url(
url_for(endpoint, **(endpoint_kwargs or {})),
@@ -2473,7 +2474,7 @@ def client_request(logged_in_client, mocker, service_one): # noqa (C901 too com
_expected_status=302,
_optional_args="",
_content_type=None,
**endpoint_kwargs
**endpoint_kwargs,
):
return ClientRequest.post_response_from_url(
url_for(endpoint, **(endpoint_kwargs or {})) + _optional_args,
@@ -3519,89 +3520,6 @@ 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_context(browser):
context = browser.new_context()
return 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)
return context
@pytest.fixture()
def fake_markdown_file():
input = "#Test"

View File

View File

@@ -0,0 +1,107 @@
import os
import re
import pytest
E2E_TEST_URI = os.getenv("NOTIFY_E2E_TEST_URI")
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(f"{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_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)
return context
@pytest.fixture(scope="session")
def end_to_end_context(browser):
context = browser.new_context()
return context
@pytest.fixture(scope="session")
def authenticated_page(end_to_end_context):
# Open a new page and go to the site.
page = end_to_end_context.new_page()
page.goto(f"{E2E_TEST_URI}/")
# Wait for the next page to fully load.
page.wait_for_load_state("domcontentloaded")
# Sign in to the site - E2E test accounts are set to flow through.
sign_in_button = page.get_by_role("link", name="Sign in")
sign_in_button.click()
# Wait for the next page to fully load.
page.wait_for_load_state("domcontentloaded")
return page

View File

@@ -4,35 +4,11 @@ import re
from playwright.sync_api import expect
def _bypass_sign_in(end_to_end_context):
# Open a new page and go to the staging site.
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. Because we are loading the email and password
sign_in_button.click()
# Wait for the next page to fully load.
page.wait_for_load_state("domcontentloaded")
return page
E2E_TEST_URI = os.getenv("NOTIFY_E2E_TEST_URI")
def test_add_new_service_workflow(end_to_end_context):
# page = end_to_end_context.new_page()
page = _bypass_sign_in(end_to_end_context)
page.goto(os.getenv("NOTIFY_E2E_TEST_URI"))
# sign_in_button = page.get_by_role("link", name="Sign in")
#
# Test trying to sign in. Because we are loading the email and password
# sign_in_button.click()
#
# Wait for the next page to fully load.
page.wait_for_load_state("domcontentloaded")
def test_add_new_service_workflow(authenticated_page, end_to_end_context):
page = authenticated_page
# Prepare for adding a new service later in the test.
current_date_time = datetime.datetime.now()
@@ -41,9 +17,7 @@ def test_add_new_service_workflow(end_to_end_context):
browser_type=end_to_end_context.browser.browser_type.name,
)
accounts_uri = "{}accounts".format(os.getenv("NOTIFY_E2E_TEST_URI"))
page.goto(accounts_uri)
page.goto(f"{E2E_TEST_URI}/accounts")
# Check to make sure that we've arrived at the next page.
page.wait_for_load_state("domcontentloaded")
@@ -82,24 +56,13 @@ def test_add_new_service_workflow(end_to_end_context):
# 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)
expect(federal_radio_button).to_be_enabled()
# Trying to click directly on the radio button resulted in a "not in viewport error" and this is the
# suggested workaround. Googling, the reason seems to be that there might be some (invisible?) css positioned
# above the radio button itself.
page.click("text='Federal government'")
# Click on add service.
add_service_button.click()
@@ -108,7 +71,7 @@ def test_add_new_service_workflow(end_to_end_context):
page.wait_for_load_state("domcontentloaded")
# Check for the service name title and heading.
service_heading = page.get_by_text(new_service_name)
service_heading = page.get_by_text(new_service_name, exact=True)
expect(service_heading).to_be_visible()
expect(page).to_have_title(re.compile(new_service_name))

View File

@@ -3,11 +3,13 @@ import re
from playwright.sync_api import expect
E2E_TEST_URI = os.getenv("NOTIFY_E2E_TEST_URI")
def test_landing_page(end_to_end_context):
# Open a new page and go to the staging site.
# Open a new page and go to the site.
page = end_to_end_context.browser.new_page()
page.goto(os.getenv("NOTIFY_E2E_TEST_URI"))
page.goto(f"{E2E_TEST_URI}/")
# Check to make sure that we've arrived at the next page.
page.wait_for_load_state("domcontentloaded")
@@ -17,7 +19,8 @@ def test_landing_page(end_to_end_context):
# Retrieve some prominent elements on the page for testing.
main_header = page.get_by_role(
"heading", name="Send text messages to your participants"
"heading",
name="Reach people where they are with government-powered text messages",
)
sign_in_button = page.get_by_role("link", name="Sign in")
benefits_studio_email = page.get_by_role("link", name="tts-benefits-studio@gsa.gov")
@@ -51,7 +54,7 @@ def test_landing_page(end_to_end_context):
# 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_context.new_page()
# page.goto(os.getenv("NOTIFY_E2E_TEST_URI"))
# page.goto(f"{E2E_TEST_URI}/")
# print(f"test_sign_in_and_mfa_pages initial {page}")
#
# sign_in_button = page.get_by_role("link", name="Sign in")