Source code for pages.web.team

"""The OpenStax team and advisor page."""

from pypom import Region
from selenium.common.exceptions import WebDriverException
from selenium.webdriver.common.by import By

from pages.web.base import WebBase
from utils.utilities import Utility
from utils.web import Web


[docs]class Individual(Region): """A base class for members of the OpenStax team.""" _name_locator = (By.CSS_SELECTOR, '.name') _bio_locator = (By.CSS_SELECTOR, '.bio') @property def name(self): """Return the advisor's name.""" return self.find_element(*self._name_locator).text.strip() @property def bio(self): """Return the advisor's biography.""" return self.find_element(*self._bio_locator).text.strip()
[docs] def view(self): """Scroll to the advisor's card.""" Utility.scroll_to(self.driver, element=self.root, shift=-80) return self
@property def is_visible(self): """Return True if the person's card is in the viewport.""" return Utility.in_viewport(self.driver, element=self.root, ignore_bottom=True, display_marks=True)
[docs]class Team(WebBase): """The OpenStax team and advisors page.""" URL_TEMPLATE = '/team' PHONE = 'accordion-region' FULL = 'tab-content' PERSON = ' .people-tab:not(.inline-bios) .card:not(.bio)' ADVISOR = ' .people-tab.inline-bios .card:not(.bio)' FAB = ' ' _title_locator = (By.CSS_SELECTOR, '.hero h1') _blurb_locator = (By.CSS_SELECTOR, _title_locator[1] + ' ~ div') _banner_locator = (By.CSS_SELECTOR, '.picture-content img') _tab_locator = (By.CSS_SELECTOR, '.tab-group h3') _bar_locator = (By.CSS_SELECTOR, '.accordion-item') _advisor_locator_phone = (By.CSS_SELECTOR, PHONE + ADVISOR) _people_locator_phone = (By.CSS_SELECTOR, PHONE + PERSON) _fab_locator_phone = (By.CSS_SELECTOR, PHONE + FAB) _people_locator_full = (By.CSS_SELECTOR, FULL + PERSON) _advisor_locator_full = (By.CSS_SELECTOR, FULL + ADVISOR) _fab_locator_full = (By.CSS_SELECTOR, FULL + FAB) @property def loaded(self): """Return True when banner is visible.""" return (super().loaded and Utility.is_image_visible(self.driver, image=self.banner))
[docs] def is_displayed(self): """Return True if the team page is displayed.""" return ('team effort' in self.title and self.banner.is_displayed())
@property def title(self): """Return the page title.""" return self.find_element(*self._title_locator).text @property def subheading(self): """Return the subheading text.""" return self.find_element(*self._blurb_locator).text @property def banner(self): """Return the banner image element.""" return self.find_element(*self._banner_locator) @property def tabs(self): """Access the group tabs.""" return [self.Tab(self, tab) for tab in self.find_elements(*self._tab_locator)] @property def bars(self): """Access the phone view group bars.""" return [self.Bar(self, bar) for bar in self.find_elements(*self._bar_locator)] @property def people(self): """Access the OpenStax staff bio cards.""" return self._person_selector(self._people_locator_phone, self._people_locator_full, self.Person) @property def advisors(self): """Access the strategic advisors bio cards.""" return self._person_selector(self._advisor_locator_phone, self._advisor_locator_full, self.Advisor) @property def fab(self): """Access the faculty adisory board bio cards.""" return self._person_selector(self._fab_locator_phone, self._fab_locator_full, self.FacultyAdvisor) def _person_selector(self, phone, full, group): """Select the appropriate list of people.""" mobile = self.driver.get_window_size().get('width') <= Web.PHONE locator = phone if mobile else full return [group(self, card) for card in self.find_elements(*locator)]
[docs] class Tab(Region): """A group tab view.""" @property def name(self): """Return the tab group name.""" return self.root.text.strip()
[docs] def select(self): """Select a group tab to view.""" Utility.click_option(self.driver, element=self.root) return self.page
@property def is_open(self): """Return True if the tab is currently selected.""" return self.root.get_attribute('aria-current') == 'page'
[docs] class Bar(Region): """A group bar for a phone view accordion menu.""" _name_locator = (By.CSS_SELECTOR, '.label') _toggle_locator = (By.CSS_SELECTOR, '.control-bar') _open_status_locator = (By.CSS_SELECTOR, '.control-bar .chevron') @property def name(self): """Return the bar region group name.""" return self.find_element(*self._name_locator).text.strip() @property def toggle_bar(self): """Return the toggle bar element.""" return self.find_element(*self._toggle_locator)
[docs] def toggle(self): """Open or close the bar region.""" Utility.click_option(self.driver, element=self.toggle_bar) return self.page
@property def is_open(self): """Return True if the accordion region is open.""" chevron = self.find_element(*self._open_status_locator) return 'chevron-down' in chevron.get_attribute('innerHTML')
[docs] class Person(Individual): """A staff member bio.""" _image_locator = (By.CSS_SELECTOR, 'img') _role_locator = (By.CSS_SELECTOR, '.name ~ div') _bio_selector = '.card.bio.tooltip' @property def headshot(self): """Return the headshot image.""" return self.find_element(*self._image_locator) @property def role(self): """Return the person's role at OpenStax.""" return self.find_element(*self._role_locator).text.strip() @property def bio(self): """Return the person's biography blurb. Use a script because the bio is inserted inline with the cards and doesn't fall within the card tree. """ script = ('return document.querySelector("{locator}").textContent;' .format(locator=self._bio_selector)) return self.driver.execute_script(script)
[docs] def select(self): """Click on the person's card to open or close the bio.""" Utility.click_option(self.driver, element=self.root) return self
@property def has_bio(self): """Return True if the person has an associated biography.""" return self.root.get_attribute('role') == 'button' @property def bio_visible(self): """Return True if the bio is currently open.""" try: return self.bio except WebDriverException: return False
[docs] class Advisor(Individual): """A strategic advisor bio."""
[docs] class FacultyAdvisor(Individual): """A faculty advisory board member bio."""