Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat: smoke tests #2623

Draft
wants to merge 12 commits into
base: feat/playwright-headed-mode
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ test = [
"pytest-django",
"pytest-mock",
"pytest-playwright", # only for writing tests. run tests using playwright Docker Compose service
"pyotp",
"pytest-socket",
]

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@


def test_dev_healthcheck(page: Page):
page.goto("https://dev-benefits.calitp.org/healthcheck")
page.goto("/healthcheck")

expect(page.get_by_text("Healthy")).to_be_visible()
1 change: 1 addition & 0 deletions tests/playwright/requirements.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
playwright==1.48.0 # needs to match version on Docker image
pyotp
pytest
pytest-playwright
pytest-reporter-html1
4 changes: 3 additions & 1 deletion tests/playwright/run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,6 @@

set -e

pytest
BASE_URL="https://dev-benefits.calitp.org"

pytest --base-url $BASE_URL
154 changes: 154 additions & 0 deletions tests/playwright/smoke_tests/models.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
"""
Page object models for Playwright tests.

https://playwright.dev/python/docs/pom
"""

from playwright.sync_api import Page


class Index:
def __init__(self, page: Page):
self.page = page

def select_agency(self, agency_name):
page = self.page
page.get_by_role("link", name="Choose your Provider").click()
page.get_by_role("link", name=agency_name).click()

return EligibilityIndex(page)


class EligibilityIndex:
def __init__(self, page: Page):
self.page = page

def select_flow(self, flow_name):
page = self.page
page.get_by_label(flow_name).check()
page.wait_for_load_state("networkidle") # wait for reCAPTCHA to finish loading
page.get_by_role("button", name="Choose this benefit").click()

return EligibilityStart(page)


class EligibilityStart:
def __init__(self, page: Page):
self.page = page

def click_continue(self):
page = self.page
page.get_by_role("button", name="Continue").click()

return EligibilityConfirm(page)

def get_started_with_login_gov(self):
page = self.page
page.get_by_role("link", name="Get started with Login.gov").click()

return LoginGov(page)

def continue_to_medicare_gov(self):
page = self.page
page.get_by_role("button", name="Continue to Medicare.gov").click()

return MedicareGov(page)


class EligibilityConfirm:
def __init__(self, page: Page):
self.page = page

def submit_form(self, sub, name):
page = self.page
page.get_by_placeholder("12345").click()

page.get_by_placeholder("12345").fill(sub)
page.keyboard.press("Tab")

page.get_by_placeholder("Hernandez-Demarcos").fill(name)

page.get_by_role("button", name="Find my record").click()

return EnrollmentIndex(page)


class LoginGov:
def __init__(self, page: Page):
self.page = page

def sign_in(self, username, password):
page = self.page
page.get_by_label("Email address").click()
page.get_by_label("Email address").fill(username)
page.get_by_label("Email address").press("Tab")

page.get_by_label("Password", exact=True).fill(password)

page.get_by_role("button", name="Sign in").click()

def enter_otp(self, one_time_password):
page = self.page
page.get_by_label("One-time code").click()
page.get_by_label("One-time code").fill(one_time_password)

page.get_by_role("button", name="Submit").click()

return EnrollmentIndex(page)


class MedicareGov:
def __init__(self, page: Page):
self.page = page

def log_in(self, username, password):
page = self.page

page.get_by_label("Username", exact=True).click()
page.get_by_label("Username", exact=True).fill(username)

page.get_by_label("Password").fill(password)

page.get_by_role("button", name="Log in").click()

def accept_consent_screen(self):
page = self.page
page.get_by_role("button", name="Connect").click()

return EnrollmentIndex(page)


class EnrollmentIndex:
def __init__(self, page: Page):
self.page = page

def enroll(self, cardholder_name, card_number, expiration, security_code):
page = self.page

with page.expect_popup() as popup_info:
page.get_by_role("button", name="Enroll").click()

popup = popup_info.value
popup.wait_for_timeout(3000)

popup.get_by_text("Cardholder name").click()

popup.get_by_label("Cardholder name").fill(cardholder_name)
popup.keyboard.press("Tab")

popup.get_by_label("Card number").fill(card_number)
popup.keyboard.press("Tab")

popup.get_by_label("mm/yy").fill(expiration)
popup.keyboard.press("Tab")

popup.get_by_text("Security code", exact=True).click()
popup.get_by_label("Security code").fill(security_code)

# trigger form validation - not sure why their form behaves this way
popup.keyboard.press("Shift+Tab")
popup.keyboard.press("Shift+Tab")
popup.keyboard.press("Shift+Tab")
popup.keyboard.press("Tab")

popup.get_by_role("group", name="Enter your card details").get_by_role("button").click()
23 changes: 23 additions & 0 deletions tests/playwright/smoke_tests/test_agency_flow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
from playwright.sync_api import Browser, expect

from models import Index


def test_agency_card_flow(browser: Browser, base_url):
context = browser.new_context(user_agent="cal-itp/benefits-smoke-test")
page = context.new_page()

page.goto(base_url)

index = Index(page)
eligibility_index = index.select_agency("California State Transit")
eligibility_start = eligibility_index.select_flow("Agency Cardholder")
eligibility_confirm = eligibility_start.click_continue()
enrollment_index = eligibility_confirm.submit_form("71162", "Box")
enrollment_index.enroll("Test User", "4111 1111 1111 1111", "12/34", "123")

# enrollment can take a bit
page.wait_for_timeout(10000)

success_message = page.get_by_text("You can now use your contactless card to tap to ride with a reduced fare!")
expect(success_message).to_be_visible()
96 changes: 96 additions & 0 deletions tests/playwright/smoke_tests/test_login_gov_flow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
import os

from playwright.sync_api import Browser, expect
import pyotp

from models import Index


def test_older_adult_flow(browser: Browser, base_url):
context = browser.new_context(user_agent="cal-itp/benefits-smoke-test")
page = context.new_page()

page.goto(base_url)

index = Index(page)
eligibility_index = index.select_agency("California State Transit")
eligibility_start = eligibility_index.select_flow("Older Adult")

login_gov = eligibility_start.get_started_with_login_gov()

username = os.environ.get("PLAYWRIGHT_LOGIN_GOV_OLDER_ADULT_USERNAME")
password = os.environ.get("PLAYWRIGHT_LOGIN_GOV_OLDER_ADULT_PASSWORD")
login_gov.sign_in(username, password)

authenticator_secret = os.environ.get("PLAYWRIGHT_LOGIN_GOV_OLDER_ADULT_AUTHENTICATOR_SECRET")
# create instance of "authenticator app"
totp = pyotp.TOTP(authenticator_secret)
enrollment_index = login_gov.enter_otp(totp.now())

enrollment_index.enroll("Test User", "4111 1111 1111 1111", "12/34", "123")

# enrollment can take a bit
page.wait_for_timeout(10000)

success_message = page.get_by_text("You can now use your contactless card to tap to ride with a reduced fare!")
expect(success_message).to_be_visible()


def test_us_veteran_flow(browser: Browser, base_url):
context = browser.new_context(user_agent="cal-itp/benefits-smoke-test")
page = context.new_page()

page.goto(base_url)

index = Index(page)
eligibility_index = index.select_agency("California State Transit")
eligibility_start = eligibility_index.select_flow("U.S. Veteran")

login_gov = eligibility_start.get_started_with_login_gov()

username = os.environ.get("PLAYWRIGHT_LOGIN_GOV_VETERAN_USERNAME")
password = os.environ.get("PLAYWRIGHT_LOGIN_GOV_VETERAN_PASSWORD")
login_gov.sign_in(username, password)

authenticator_secret = os.environ.get("PLAYWRIGHT_LOGIN_GOV_VETERAN_AUTHENTICATOR_SECRET")
# create instance of "authenticator app"
totp = pyotp.TOTP(authenticator_secret)
enrollment_index = login_gov.enter_otp(totp.now())

enrollment_index.enroll("Test User", "4111 1111 1111 1111", "12/34", "123")

# enrollment can take a bit
page.wait_for_timeout(10000)

success_message = page.get_by_text("You can now use your contactless card to tap to ride with a reduced fare!")
expect(success_message).to_be_visible()


def test_calfresh_cardholder_flow(browser: Browser, base_url):
context = browser.new_context(user_agent="cal-itp/benefits-smoke-test")
page = context.new_page()

page.goto(base_url)

index = Index(page)
eligibility_index = index.select_agency("California State Transit")
eligibility_start = eligibility_index.select_flow("CalFresh Cardholder")

login_gov = eligibility_start.get_started_with_login_gov()

username = os.environ.get("PLAYWRIGHT_LOGIN_GOV_CALFRESH_USERNAME")
password = os.environ.get("PLAYWRIGHT_LOGIN_GOV_CALFRESH_PASSWORD")
login_gov.sign_in(username, password)

authenticator_secret = os.environ.get("PLAYWRIGHT_LOGIN_GOV_CALFRESH_AUTHENTICATOR_SECRET")
# create instance of "authenticator app"
totp = pyotp.TOTP(authenticator_secret)
enrollment_index = login_gov.enter_otp(totp.now())

enrollment_index.enroll("Test User", "4111 1111 1111 1111", "12/34", "123")

# enrollment can take a bit
page.wait_for_timeout(10000)

reenrollment_error_message = page.get_by_text("You are still enrolled in this benefit")
expect(reenrollment_error_message).to_be_visible()
33 changes: 33 additions & 0 deletions tests/playwright/smoke_tests/test_medicare_flow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import os
from playwright.sync_api import Browser, expect

from models import Index


def test_medicare_cardholder_flow(browser: Browser, base_url):
context = browser.new_context(user_agent="cal-itp/benefits-smoke-test")
page = context.new_page()

page.goto(base_url)

index = Index(page)
eligibility_index = index.select_agency("California State Transit")
eligibility_start = eligibility_index.select_flow("Medicare Cardholder")

# avoid looking like a bot
page.add_init_script("delete Object.getPrototypeOf(navigator).webdriver")

medicare_gov = eligibility_start.continue_to_medicare_gov()

username = os.environ.get("PLAYWRIGHT_MEDICARE_GOV_USERNAME")
password = os.environ.get("PLAYWRIGHT_MEDICARE_GOV_PASSWORD")
medicare_gov.log_in(username, password)
enrollment_index = medicare_gov.accept_consent_screen()

enrollment_index.enroll("Test User", "4111 1111 1111 1111", "12/34", "123")

# enrollment can take a bit
page.wait_for_timeout(10000)

success_message = page.get_by_text("You can now use your contactless card to tap to ride with a reduced fare!")
expect(success_message).to_be_visible()
Loading