modules/page_object_newtab.py (74 lines of code) (raw):

import logging from selenium.webdriver.common.by import By from selenium.webdriver.remote.webelement import WebElement from modules.page_base import BasePage class L10nAboutNewtab: """ Class to set text constants for Newtab localization. """ def __init__(self, lang_code: str): # TODO: make l10ns for DE and FR once we are testing these builds if lang_code in ["enUS", "enGB", "deDE", "frFR"]: self.popular_topics = [ "Self improvement", "Food", "Entertainment", "Health & fitness", "Science", "More recommendations ›", ] class AboutNewtab(BasePage): """ Class that describes the POM of the about:newtab page. Attributes ---------- driver: selenium.webdriver.Firefox WebDriver object under test lang_code: str The ISO-639-1 code of the language, followed by the ISO-3166-1 alpha-2 code of the region (country). examples: enUS, zhCN, jaJP, frFR constants: self.L10nAboutNewtab Instantiation of the constants object """ URL_TEMPLATE = "about:newtab" TOP_SITES_TOTAL = [7, 8] REC_ARTICLE_TOTAL = 21 def set_language_code(self, lang_code: str) -> BasePage: """ Set the language code of the object, set self.constants as well """ self.language = lang_code self.constants = L10nAboutNewtab(lang_code) return self def count_top_sites(self) -> int: """ Find the top sites area and return the number of tiles in it """ top_sites_list = self.get_element("top-sites-list") top_site_nodes = top_sites_list.find_elements(By.TAG_NAME, "li") return len(top_site_nodes) def get_recommended_articles(self) -> list[WebElement]: """ Return a list of all recommended article nodes """ article_root = self.get_element("recommended-by-pocket-list") return article_root.find_elements(By.TAG_NAME, "article") def check_article_alignment(self) -> bool: """ Check that all article card elements are lined up with the elements in their columns """ recd_articles = self.get_recommended_articles() number_of_articles = len(recd_articles) for i in range(number_of_articles - 3, number_of_articles): article_x = recd_articles[i].location.get("x") for j in range(i - 3, -1, -3): comparison_x = recd_articles[j].location.get("x") assert article_x == comparison_x return True def count_sponsored_articles(self) -> int: """ Return the total number of sponsored article cards """ return len(self.get_elements("story-sponsored-footer")) def check_popular_topics(self) -> bool: """ Ensure that all the Popular Topics are as expected """ poptopics_list = self.get_element("popular-topics-list") checked_topics = [] logging.info(f"Topics: {self.constants.popular_topics}") for li in poptopics_list.find_elements(By.TAG_NAME, "li"): this_topic = li.get_attribute("innerText") logging.info(f"Topic innerText = {this_topic}") assert this_topic in self.constants.popular_topics checked_topics.append(this_topic) assert checked_topics == self.constants.popular_topics return True def check_layout(self) -> BasePage: """ Main method to check about:newtab layout is as expected """ self.element_exists("incontent-search-input") logging.info("Search bar exists") self.element_exists("recent-activity-section") for i in range(1, self.REC_ARTICLE_TOTAL + 1): document_height = self.driver.execute_script( "return document.body.scrollHeight" ) target_y = int(document_height) // i # Sometimes we need to scroll around to force the article tile to load # We're waiting until the article tiles load to resolve flake for _ in range(2): self.driver.execute_script( "window.scrollTo(0, document.body.scrollHeight);" ) self.driver.execute_script("window.scrollTo(0, 0);") self.driver.execute_script(f"window.scrollTo(0, {target_y});") self.get_element("loaded-image-by-index", labels=[str(i)]) assert len(self.get_recommended_articles()) == self.REC_ARTICLE_TOTAL assert self.check_article_alignment() assert self.count_sponsored_articles() > 0 assert self.check_popular_topics() logging.info(f"Found {self.count_top_sites()} top sites") # ODD: Sometimes we get 7 top sites, not 8 assert self.count_top_sites() in self.TOP_SITES_TOTAL