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

three rex-web tests converted to playwright #2391

Merged
merged 11 commits into from
Mar 5, 2025
18 changes: 16 additions & 2 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ defaults:
working-directory: playwright

jobs:
Test:
runs-on: ubuntu-latest
playwright-typescript:
runs-on: ubuntu-22.04

steps:
- uses: actions/checkout@v4
Expand All @@ -22,3 +22,17 @@ jobs:
- run: npx playwright install-deps
- run: npx playwright install
- run: npm run test

playwright-python:
runs-on: ubuntu-22.04
env:
BASE_URL: ${{ github.event.inputs.base_url }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
with:
python-version: '3.11'
cache: 'pip' # caching pip dependencies
- run: pip install -r requirements.txt
- run: playwright install chromium --with-deps
- run: pytest --tb=long --showlocals --base-url="${BASE_URL:-https://staging.openstax.org}" -vvv e2e
2 changes: 2 additions & 0 deletions playwright/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Import fixtures
pytest_plugins = "e2e.ui.fixtures.ui"
42 changes: 42 additions & 0 deletions playwright/e2e/ui/fixtures/ui.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import requests

import pytest
import pytest_asyncio

from playwright.async_api import async_playwright


@pytest_asyncio.fixture
async def chrome_page():
async with async_playwright() as playwright:
browser_obj = playwright.chromium
if browser_obj:
ch_browser = await browser_obj.launch(headless=True, slow_mo=1200, timeout=120000)
context = await ch_browser.new_context()
page = await context.new_page()
yield page

await ch_browser.close()


@pytest.fixture
def abl_approved():
"""Return list of dictionaries of approved books in ABL json"""
abl_url = "https://corgi.ce.openstax.org/api/abl/"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

abl_dict = requests.get(abl_url).json()
return abl_dict


@pytest.fixture
def abl_uuids_slugs():
"""Returns dictionary of uuid:slug values of all collection entries in ABL api"""

uuids_slugs = {}

abl_url = "https://corgi.ce.openstax.org/api/abl/"
abl_dict = requests.get(abl_url).json()

for i in abl_dict:
uuids_slugs[i["uuid"]] = i["slug"]

return uuids_slugs
285 changes: 285 additions & 0 deletions playwright/e2e/ui/pages/home.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,285 @@
import asyncio
import pytest

from playwright.async_api import expect

import re


class HomeRex:
def __init__(self, page):
self.page = page

# Subjects homepage

@property
def subjects_page_menu(self):
return self.page.get_by_role("button", name="Subjects")

@pytest.mark.asyncio
async def click_subjects_page_menu(self):
await self.subjects_page_menu.hover()

@property
def subjects_homepage_link(self):
return self.page.get_by_role("link", name="All")

@pytest.mark.asyncio
async def click_subjects_homepage_link(self):
await self.subjects_homepage_link.click()

@property
def language_selector_section(self):
return self.page.locator("section.language-selector-section")

@property
def subjects_listing_section(self):
return self.page.locator("section.subjects-listing")

@property
def about_openstax_section(self):
return self.page.locator("section.about-openstax > div > h2")

@property
def learn_about_openstax_link(self):
return self.page.locator("a").get_by_text("Learn about OpenStax")

@pytest.mark.asyncio
async def click_learn_about_openstax_link(self):
await self.learn_about_openstax_link.click()

@property
def about_page(self):
return self.page.locator("id=main")

@property
def book_toc_link(self):
return self.page.locator("div.option.toc-option")

@pytest.mark.asyncio
async def click_book_toc_link(self):
await self.book_toc_link.click()

@property
def book_toc_content(self):
return self.page.locator("div.toc-slideout-contents > div > div")

@property
def book_toc_slideout_is_visible(self):
return self.page.locator("div.toc-slideout-contents")

@property
def book_link(self):
return self.page.locator("menu > li:nth-child(5) > a").get_by_text("Economics")

@pytest.mark.asyncio
async def click_book_link(self):
await self.book_link.click()

@property
def book_cover_link(self):
return self.page.locator("a").get_by_text("Principles of Macroeconomics 3e")

@pytest.mark.asyncio
async def click_book_cover_link(self):
await self.book_cover_link.click()

@property
def view_online_link(self):
return self.page.locator("a").get_by_text("View online")

@pytest.mark.asyncio
async def click_view_online_link(self):
await self.view_online_link.click()

@property
def go_to_your_book_link(self):
return self.page.locator("a.btn.go-to").get_by_text("Go to your ")

@pytest.mark.asyncio
async def click_go_to_your_book_link(self):
await self.go_to_your_book_link.click()

@property
def highlights_option_is_visible(self):
return self.page.locator("nudge-study-tools > button").get_by_text("Highlights")

@property
def order_a_print_copy_link_is_visible(self):
return self.page.locator("div.BuyBook__BuyBook > a").get_by_text("Order a print copy")

@property
def citation_attribution_link_is_visible(self):
return self.page.locator("div.ContentPane__Wrapper-sc-6et83r-0.hPmLNC > details > summary > "
"span").get_by_text("Citation/Attribution")

@property
def giving_tuesday_popup_is_visible(self):
return self.page.locator("div.text-side > h1").get_by_text("Embrace the spirit of Giving Tuesday today!")

@property
def giving_tuesday_popup_close_icon(self):
return self.page.locator("button.put-away.no-title-bar")

@pytest.mark.asyncio
async def close_giving_tuesday_popup(self):
await self.giving_tuesday_popup_close_icon.click()

# Philanthropic support

@property
def philanthropic_support_section(self):
return self.page.locator("section.philanthropic-support")

@property
def our_impact_link(self):
return self.page.locator("a").get_by_text("Learn more about our impact")

@pytest.mark.asyncio
async def click_our_impact_link(self):
await self.our_impact_link.click()

@property
def give_today_link_is_visible(self):
return self.page.locator("#footer").get_by_role("link", name="Give today")

@pytest.mark.asyncio
async def click_give_today_link(self):
await self.give_today_link_is_visible.click()

# Subjects page footer section

@property
def footer_section(self):
return self.page.locator("id=footer")

@property
def footer_section_help_is_visible(self):
return self.page.locator("div.column.col1")

@property
def footer_section_openstax_is_visible(self):
return self.page.locator("div.column.col2")

@property
def footer_section_policies_is_visible(self):
return self.page.locator("div.column.col3")

@property
def footer_section_bottom_is_visible(self):
return self.page.locator("div.bottom")

@property
@pytest.mark.asyncio
async def footer_section_license_link(self):
return await self.page.locator("div.copyrights").get_by_role("link").get_attribute("href")

# Book page navigation

@property
def content_page_previous_next_page_bar_is_visible(self):
return self.page.locator("div.PrevNextBar__BarWrapper-sc-13m2i12-3.fEZPiF")

@property
def content_page_previous_link_is_visible(self):
return self.page.locator("a").get_by_text('Previous')

@pytest.mark.asyncio
async def click_content_page_previous_link(self):
await self.content_page_previous_link_is_visible.click()

@property
def content_page_next_link_is_visible(self):
return self.page.locator("a").get_by_text('Next')

@pytest.mark.asyncio
async def click_content_page_next_link(self):
await self.content_page_next_link_is_visible.click()

@property
def content_page_black_overlay_is_visible(self):
return self.page.locator("div.styles__NudgeContentWrapper-hrv0cf-"
"1.fpMWRn").get_by_text("The study tools you need. 100% FREE! Highlight, take notes, "
"and make your own study guides. It's all free.")

@property
def content_page_black_overlay_close(self):
return self.page.locator("div.styles__NudgeWrapper-hrv0cf-0.fJZGzd > button")

@pytest.mark.asyncio
async def click_content_page_black_overlay_close(self):
await self.content_page_black_overlay_close.click()

@property
def subject_listing_book_is_visible(self):
return self.page.locator("a").get_by_text("Astronomy")

@pytest.mark.asyncio
async def click_subject_listing_book(self):
await self.subject_listing_book_is_visible.click()

@property
def book_selection(self):
return self.page.locator("div").get_by_text("Astronomy 2e")

@pytest.mark.asyncio
async def click_book_selection(self):
await self.book_selection.click()

@property
def buy_print_copy_button_is_visible(self):
return self.page.locator("a").get_by_text("Buy a print copy")

@pytest.mark.asyncio
async def click_buy_print_copy_button(self):
await self.buy_print_copy_button_is_visible.click()

@property
def bookstore_box_is_visible(self):
return self.page.locator("div").get_by_text("Bookstore")

@property
def order_options_button_is_visible(self):
return self.page.locator("a").get_by_text("Order options")

@pytest.mark.asyncio
async def order_options_href(self):
await self.page.locator("a").get_by_text("Order options").get_attribute('href')

@pytest.mark.asyncio
async def click_order_options_button(self):
await self.order_options_button_is_visible.click()

@property
def highlight_recommended_popup_is_visible(self):
return self.page.locator("span").get_by_text("Recommended")

@property
def cookies_accept_is_visible(self):
return self.page.locator("div.osano-cm-dialog__buttons.osano-cm-buttons").get_by_text("Accept")

@pytest.mark.asyncio
async def click_cookies_accept(self):
await self.cookies_accept_is_visible.click()

@property
def cookieyes_accept_is_visible(self):
return self.page.locator("div.cky-notice-btn-wrapper > button.cky-btn.cky-btn-accept")

@pytest.mark.asyncio
async def click_cookieyes_accept(self):
await self.cookieyes_accept_is_visible.click()

@property
def toc_is_visible(self):
return self.page.locator("span").get_by_text("Table of contents")

@property
def bookbanner_is_visible(self):
return self.page.locator("div.bookbanner")

# Accessibility page (hidden link: go to accessibility page)

@property
def accessibility_help_content(self):
return self.page.locator("#maincontent > div")
Loading
Loading