import datetime import logging import time import allure from assertpy import assert_that from dateutil import rrule from selenium.webdriver import ActionChains from selenium.webdriver.common.keys import Keys from ui_automation_framework.core import BasePage, TestStatus from ui_automation_framework.utils import CoreConfig from ui_automation_framework.utils import logger as cl from app.api_client import ApiClient from app.mysql_db_client_custom import MySqlClient from app.src.pages.artist_page import ArtistPage from app.src.pages.chart_digest import ChartDigestPage from app.src.pages.global_search import GlobalSearch from app.src.pages.gtp_cpot_popup import GTPCPOTPopup from app.src.pages.gtp_hh_modal import GTPHotHitsModal from app.src.pages.track_page import TrackPage class GlobalTrackPrioritiesPage(BasePage): log = cl.Logger(logging.DEBUG) hd_filter_market = "hd_filter_market" hd_date = "hd_date" circle_new = "new" TAB_OP = "ongoing-priorities" TAB_BU = "bubbling-under" TAB_OH = "orchard-highlight" TAB_CH = "catalogue-highlight" NEW_ENTRY = "New Entry" RE_ENTRY = "Re-Entry" DATEPICKER_COLLAPSED_BG_COLOR = "rgba(242, 242, 247, 1)" DATEPICKER_ENTER_ICON = "rgba(214, 216, 230, 1)" DATEPICKER_TODAY_DATE_COLOR = "rgba(255, 60, 129, 1)" CALENDAR_GRID_FIRST_WEEKDAY = "MO" DATEPICKER_ARROW_HOVER = "rgba(229, 245, 254, 1)" DATEPICKER_DISABLED_ARROW_COLOR = "rgba(214, 216, 230, 1)" DATEPICKER_SELECTED_DATE_COLOR = "rgba(255, 255, 255, 1)" DATEPICKER_SELECTED_DATE_BACKGROUND_COLOR = "rgba(0, 0, 0, 1)" DATEPICKER_HOVERED_DATE_COLOR = "rgba(1, 156, 254, 1)" DATEPICKER_HOVERED_DATE_BACKGROUND_COLOR = "rgba(229, 245, 254, 1)" DATEPICKER_VALIDATION_MESSAGE = "Please enter full date." def __init__(self, driver): super().__init__(driver) self.driver = driver self.gtp_locators = self.get_page_locators("GlobalTrackPrioritiesPage", "global_track_priorities_elements.json") self.gtp_hhm = GTPHotHitsModal(self.driver) self.gtp_cpot_popup = GTPCPOTPopup(self.driver) self.chart_digest = ChartDigestPage(self.driver) self.trackPage = TrackPage(self.driver) self.artist_page = ArtistPage(self.driver) self.global_search = GlobalSearch(self.driver) self.sql_client = MySqlClient() self.api_client = ApiClient() self.ts = TestStatus(self.driver) @allure.step("Verify GTP elements") def verify_gtp_elements(self): spotify_icon = self.is_element_displayed(*self.locator(self.gtp_locators, "spotify_icon")) gtp_header = str(self.get_text(*self.locator(self.gtp_locators, "page_header"))) datepicker = self.is_element_displayed(*self.locator(self.gtp_locators, "date_picker")) info_icon = self.is_element_displayed(*self.locator(self.gtp_locators, "info_icon")) market_dropdown = self.is_element_displayed(*self.locator(self.gtp_locators, "markets_dropdown")) self.ts.markFinal(spotify_icon, "spotify icon is displayed") self.ts.markFinal(gtp_header == "Global Track Priorities", "header is present and correct") self.ts.markFinal(datepicker, "datepicker is displayed") self.ts.markFinal(info_icon, "info icon is displayed") self.ts.markFinal(market_dropdown, "Markets drop-down is displayed") @allure.step("Verify Info icon tooltip") def verify_info_icon_tooltip(self): info_icon_tooltip = self.wait_for_element_visible(*self.locator(self.gtp_locators, "info_icon")) ActionChains(self.driver).move_to_element(to_element=info_icon_tooltip).perform() self.wait_for_element_visible(*self.locator(self.gtp_locators, "info_icon_tooltip")) tooltip_text = str(self.get_text(*self.locator(self.gtp_locators, "info_icon_tooltip"))) self.ts.markFinal( tooltip_text == "For current week there is 1-day chart data\ndelay and 2-days streams data delay.\nData is up-to-date for lookback.", f"Tooltip is displayed and correct.: {tooltip_text}", ) @allure.step("Get GTP market value") def get_gtp_market_value(self): market = self.get_text(*self.locator(self.gtp_locators, "markets_dropdown")) return market @allure.step("GTP - markets list") def get_gtp_markets_list(self): results_el = self.get_elements(*self.locator(self.gtp_locators, "gtp_markets_list")) markets_list = [self.get_text(element=e) for e in results_el] self.log.info(f"gtp markets list: {markets_list}") return markets_list @allure.step("Top Header markets list") def get_top_header_markets_list(self): self.click_element(*self.locator(self.gtp_locators, "top_header_dd")) results_top_header = self.get_elements(*self.locator(self.gtp_locators, "top_header_markets_list")) markets_list_top_header = [self.get_text(element=e) for e in results_top_header] self.log.info(f"top header markets list: {markets_list_top_header}") self.click_element(*self.locator(self.gtp_locators, "top_header_dd")) return markets_list_top_header @allure.step("GTP - verify chosen market is in bold") def verify_chosen_gtp_market_bold(self, market): market_to_choose = f"//b[contains(text(), '{market}')]" self.click_element(*self.locator(self.gtp_locators, "markets_dropdown")) bold_market = self.is_element_present(locator=market_to_choose, locator_type="xpath") self.click_element(*self.locator(self.gtp_locators, "markets_dropdown")) self.ts.markFinal(bold_market, "chosen market is bold") @allure.step("GTP Market drop down - Selecting market") def select_gtp_market(self, market): self.wait_for_element_visible(*self.locator(self.gtp_locators, "markets_dropdown")) self.scroll_to_element(*self.locator(self.gtp_locators, "markets_dropdown")) self.click_element(*self.locator(self.gtp_locators, "markets_dropdown")) market_item = f"//*[@id='gtp-market-dd']/..//*[text()='{market}']" market_item = self.get_element(market_item, "xpath") self.click_on_element_js(element=market_item) @allure.step("GTP drop down - verify hover over market item") def hover_over_gtp_market_and_verify_highlighted(self, market): self.wait_for_element_visible(*self.locator(self.gtp_locators, "markets_dropdown")) self.click_element(*self.locator(self.gtp_locators, "markets_dropdown")) market_s = f"//*[@id='gtp-market-dd']/..//*[text()='{market}']" self.is_element_displayed(locator=market_s, locator_type="xpath") market_to_hover = self.get_element(locator=market_s, locator_type="xpath") color_before_hover = market_to_hover.value_of_css_property("background-color") self.log.info("color before hover: {}".format(color_before_hover)) ActionChains(self.driver).move_to_element(to_element=market_to_hover).perform() color_after_hover = market_to_hover.value_of_css_property("background-color") self.log.info("color after hover: {}".format(color_after_hover)) self.ts.markFinal( color_after_hover != color_before_hover, "color after hover is changed: {}".format(color_after_hover != color_before_hover), ) self.click_element(*self.locator(self.gtp_locators, "markets_dropdown")) @allure.step("Verify gtp dropdown market") def gtp_drop_down_market_value(self): market_value = self.get_text(*self.locator(self.gtp_locators, "markets_dropdown")) return market_value @allure.step("Verify Top Header dropdown market") def top_header_drop_down_market_value(self): market_value = self.get_text(*self.locator(self.gtp_locators, "top_header_dd")) return market_value @allure.step("Select date in datepicker") def select_first_date_of_the_month(self): self.click_element(*self.locator(self.gtp_locators, "date_picker")) self.wait_for_element_visible(*self.locator(self.gtp_locators, "date_picker_dates_list")) month_first_day = self.get_element(*self.locator(self.gtp_locators, "date_picker_month_first_day")) ActionChains(self.driver).move_to_element(to_element=month_first_day).perform() self.click_element(*self.locator(self.gtp_locators, "date_picker_month_first_day")) self.wait_for_element_visible(*self.locator(self.gtp_locators, "date_picker")) @allure.step("Get date's value in datepicker") def get_datepicker_selected_date(self): date_selected = self.get_attribute_value(*self.locator(self.gtp_locators, "date_picker"), attribute="value") date_modified = datetime.datetime.strptime(date_selected, self.trackPage.get_date_format_from_locale()).strftime("%Y-%m-%d") self.log.info(f"date selected in datepicker: {date_modified}") return date_modified @allure.step("Verify 1st day of the current month is selected in datepicker") def verify_first_day_of_the_month_selected(self): self.wait_for_element_visible(*self.locator(self.gtp_locators, "date_picker_dates_list")) date_selected = self.get_attribute_value(*self.locator(self.gtp_locators, "date_picker"), attribute="value") date_modified = datetime.datetime.strptime(date_selected, self.trackPage.get_date_format_from_locale()).date() self.log.info(f"date selected in datepicker: {date_modified}") given_date = datetime.date.today() first_day_of_month = given_date.replace(day=1) self.log.info(f"expected first day of month: {first_day_of_month}") self.ts.markFinal(date_modified == first_day_of_month, "first day of the month is selected in the datepicker") @allure.step("Back browser button tree times") def verify_date_is_changed_to_today(self): self.wait_for_element_visible(*self.locator(self.gtp_locators, "date_picker")) date_in_datepicker = self.get_attribute_value(*self.locator(self.gtp_locators, "date_picker"), attribute="value") date_modified = datetime.datetime.strptime(date_in_datepicker, self.trackPage.get_date_format_from_locale()).date() self.log.info(f"date in datepicker: {date_modified}") today = datetime.date.today() self.log.info(f"today: {today}") self.ts.markFinal(date_modified == today, "Date is changed to today's date") @allure.step("Open page from URL") def open_gtp_page_from_url(self, market, date): url = CoreConfig.ENV_BASE_URL + "/global-track-priorities?&hd_filter_market=" + market + "&hd_date=" + date self.trackPage.open_url(url) @allure.step("Get card chart position") def get_card_chart_position(self): position = self.get_text(*self.locator(self.gtp_locators, "card_chart_position")) return position @allure.step("Verify 404 page present") def verify_404_page_present(self): page_404 = self.is_element_displayed(*self.locator(self.gtp_locators, "404_page")) self.ts.markFinal(page_404, "404 page is displayed") @allure.step("GTP - get track cards info") def get_tracks_card_info(self): main_selector = self.chart_digest.main_selector track_info = {} track_info_all = [] el_values = self.chart_digest.el_values self.wait_for_element_visible(*self.locator(self.gtp_locators, f"{main_selector}{self.chart_digest.gtp_track_name}")) tracks_count = self.get_elements(*self.locator(self.gtp_locators, f"{main_selector}{self.chart_digest.gtp_track_name}")) for t in tracks_count: for v in el_values: ind = tracks_count.index(t) self.log.info(f"index: {ind}") self.log.info(f"element: {v}") self.log.info(f"len: {len(self.get_elements(*self.locator(self.gtp_locators, f'{main_selector}{v}')))}") self.wait_for_element_visible(*self.locator(self.gtp_locators, f"{main_selector}{v}")) gtp_el = self.get_elements(*self.locator(self.gtp_locators, f"{main_selector}{v}"))[ind] gtp_el = self.get_text(element=gtp_el) track_info[v] = gtp_el track_info_all.append(track_info.copy()) self.log.info(f"tracks info gtp page: {track_info_all}") return track_info_all @allure.step("GTP - click track name and verify") def click_track_name_verify(self, position=1): self.wait_for_element_visible(*self.locator(self.gtp_locators, f"{self.chart_digest.main_selector}{self.chart_digest.gtp_track_name}")) self.wait_for_element_clickable(*self.locator(self.gtp_locators, f"{self.chart_digest.main_selector}{self.chart_digest.gtp_track_name}")) track_name_el = self.get_elements(*self.locator(self.gtp_locators, f"{self.chart_digest.main_selector}{self.chart_digest.gtp_track_name}"))[position - 1] track_name = self.get_text(element=track_name_el) self.click_element(element=track_name_el) self.trackPage.is_track_page_title_present(track_name) @allure.step("GTP - click artist name and verify") def click_artist_name_verify(self, position=1): artist_name_el = self.get_elements(*self.locator(self.gtp_locators, f"{self.chart_digest.main_selector}{self.chart_digest.gtp_artist_name}"))[position - 1] artist_name = self.get_text(element=artist_name_el) self.click_element(element=artist_name_el) self.artist_page.verify_title(artist_name) @allure.step("GTP - verify hot hits tooltip") def verify_hot_hits_tooltip_and_click(self, verify_tooltip=True): hot_hits_el = self.get_element(*self.locator(self.gtp_locators, "gtp-card-hot-hits-value")) if verify_tooltip: ActionChains(self.driver).move_to_element(to_element=hot_hits_el).perform() hint = self.get_text(locator="(//iframe/following-sibling::div/*)[last()]", locator_type="xpath") self.ts.markFinal("Current Hot Hits: " or "Previous Hot Hits: " in hint, f"hint : {hint}") self.click_on_element_js(element=hot_hits_el) self.gtp_hhm.is_modal_opened() @allure.step("GTP - open CPOT poup") def open_cpot_popup(self, open=True, position=1): if open: self.scroll_to_element(*self.locator(self.gtp_locators, "gtp-card-chart-position-button")) self.wait_for_element_visible(*self.locator(self.gtp_locators, "gtp-card-chart-position-button")) button = self.get_elements(*self.locator(self.gtp_locators, "gtp-card-chart-position-button"))[position - 1] color = "background-color" color_before = button.value_of_css_property(color) ActionChains(self.driver).move_to_element(to_element=button).perform() color_after = button.value_of_css_property(color) self.ts.markFinal(color_after != color_before, f"{color}: {color_before} \nis changed to: {color_after} after hover") self.click_element(element=button) self.gtp_cpot_popup.is_modal_opened(open) @allure.step("GTP - get chart positions value") def get_chart_position_value(self, position=1): self.wait_for_element_visible(*self.locator(self.gtp_locators, "gtp-card-chart-position-button")) value_el = self.get_elements(*self.locator(self.gtp_locators, "gtp-card-chart-position-button")) values = [self.get_text(element=v) for v in value_el] return values[position - 1] @allure.step("GTP - verify Track of the Week elements") def verify_tow_elements(self): for e in ["gtp-subtitle", "gtp-info", "gtp-info-icon"]: el = self.is_element_displayed(*self.locator(self.gtp_locators, e)) self.ts.markFinal(el, f"element: {e} is displayed") @allure.step("GTP - verify chart position circle") def verify_chart_position_circle(self, circle): circle = self.is_element_displayed(locator=f"gtp-card-chart-position-is-{circle}") self.ts.markFinal(circle, f"{circle} circle is displayed") @allure.step("GTP - verify chart position date") def verify_chart_position_date(self, market): tracks = self.chart_digest.get_gtp_tracks_count() if tracks > 0: dates_ui = [] for t in range(tracks): date_ui = self.chart_digest.get_gtp_track_info()[t]["chart-position-title"].split(" ")[-1] date_ui_modified = datetime.datetime.strptime(date_ui, self.trackPage.get_date_format_from_locale()).strftime("%Y-%m-%d") self.log.info("Charts date from UI: " + str(date_ui_modified)) dates_ui.append(date_ui_modified) chart_date = self.api_client.get_tracks_gtp()["chart_date"] date_ui_final = str(set(dates_ui)) assert_that(str(chart_date)).is_equal_to(date_ui_final.replace("{'", "").replace("'}", "")) @allure.step("GTP - get table header chart position date") def get_table_chart_position_date(self): charts_position_header = self.get_element(locator="gtp-table-cell-position") charts_position_header_text = self.get_text(element=charts_position_header) charts_position_date = charts_position_header_text.split("\n")[1] self.log.info("Chart position date: " + charts_position_date) charts_position_date_formatted = datetime.datetime.strptime(charts_position_date, self.trackPage.get_date_format_from_locale()).date() return charts_position_date_formatted @allure.step("GTP - get table header streams date") def get_table_streams_date(self): streams_header = self.get_element(locator="gtp-table-cell-streams") streams_header_text = self.get_text(element=streams_header) streams_date = streams_header_text.split("\n")[0] streams_date_formatted = datetime.datetime.strptime(streams_date, self.trackPage.get_date_format_from_locale()).strftime("%Y-%m-%d") return streams_date_formatted @allure.step("GTP - compare positions and trend with spotify chart daily") def compare_chart_position_trend_with_spotify_chart(self, market, date): value_gtp = self.get_chart_position_value() name_gtp = self.get_tracks_card_info()[0][self.chart_digest.gtp_track_name] position = int(value_gtp.split("\n")[0].replace("#", "")) index = position - 1 self.log.info(f"index: {index}") date = datetime.datetime.strptime(date, "%Y-%m-%d").date() track_from_chart = self.api_client.get_charts_tracks(vendor="spotify", market=market, date=date, type="daily")["tracks"][index] self.log.info(f"index: {index}") self.log.info(f"track from chart: {track_from_chart}") name_chart = track_from_chart["name"] position_chart = track_from_chart["position"] trend_chart = abs(int(track_from_chart["trend"])) if trend_chart > 200: trend_chart = "" else: trend_chart = f"\n{trend_chart}" value_chart = f"#{position_chart}{trend_chart}" self.ts.markFinal(name_chart == name_gtp, f"{name_chart} and {name_gtp} match") self.ts.markFinal(value_gtp == value_chart, f"{value_chart} and {value_gtp} match") @allure.step("GTP - verify Hot Hits date") def verify_hot_hits_date(self): tracks_count = self.chart_digest.get_gtp_tracks_count() if tracks_count > 0: hot_hits_date = self.get_tracks_card_info()[0]["hot-hits-title"].split(" ")[-1] hot_hits_date_ui = datetime.datetime.strptime(hot_hits_date, self.trackPage.get_date_format_from_locale()).date() hot_hits_date_db = datetime.datetime.strptime(self.sql_client.get_hot_hits_latest_date(), "%Y-%m-%d").date() self.ts.markFinal(hot_hits_date_db == hot_hits_date_ui, f"{hot_hits_date_ui} and\n{hot_hits_date_db} match") @allure.step("GTP - open Chart Position over modal from table") def open_cpot_from_table(self, position=1): self.wait_for_element_visible(*self.locator(self.gtp_locators, "table_cpot_icons")) icon = self.wait_for_element_clickable(*self.locator(self.gtp_locators, "table_cpot_icons")) if icon is not None: icons = self.get_elements(*self.locator(self.gtp_locators, "table_cpot_icons")) self.scroll_to_element(*self.locator(self.gtp_locators, "table_cpot_icons")) self.wait_for_element_visible(*self.locator(self.gtp_locators, "table_cpot_icons")) self.wait_for_element_clickable(*self.locator(self.gtp_locators, "table_cpot_icons")) self.click_element(element=icons[position - 1]) self.gtp_cpot_popup.is_modal_opened() @allure.step("GTP - switch to tab") def open_tab(self, t): selector = f"gtp-tab-{t}" self.wait_for_element_visible(f"//*[@id='gtp-tab-{t}'][string-length(.) > 0]", "xpath") self.scroll_to_element(locator=selector, locator_type="id") self.wait_for_element_clickable(locator=selector) e = self.wait_for_element_clickable(locator=selector) self.click_element(element=e) self.wait_for_element_visible("gtp-table-cell-streams-1") selected = self.get_attribute_value(element=e, attribute="data-selected") == "selected" self.ts.markFinal(selected, f"tab: {t} is selected") @allure.step("GTP - get data from table") def get_all_from_table(self, tab_name=TAB_OP): tab = self.wait_for_element_visible(f"//*[@id='gtp-tab-{tab_name}'][string-length(.) > 0]", "xpath") count = int(self.get_text(element=tab).split("(")[1].split(")")[0]) weeks_sel = "(//*[contains(@id, 'gtp-table-cell-weeks-')]//../span[@id or contains(@class, 'icon')])[{}]" track_id_loc = "(//*[contains(@id, 'track-name-')])[{}]" track_name_sel = "(//*[contains(@id, 'track-name-')]/*[string-length(text()) > 1])[{}]" artists_sel = "(//*[contains(@id, 'artist-name-')][string-length(.) > 0])[{}]" chart_positions_sel = "(//*[contains(@id, 'chart-position-')]/*[string-length(text()) > 0])[{}]" trend_sel = "//*[contains(@id, 'position-trend-{}')]" streams_sel = "gtp-table-cell-streams-{}" streams_trend_sel = "gtp-table-cell-streams-trend-{}" data = {} self.wait_for_element_visible("//*[@id='gtp-table-cell-streams-1'][string-length(.) > 0]", "xpath") for c in list(range(1, count + 1)): if c < count - 10: self.wait_for_element_visible(track_name_sel.format(c), "xpath") self.scroll_to_element(track_name_sel.format(c), "xpath") weeks_el = self.wait_for_element_visible(weeks_sel.format(c), "xpath") artists_el = self.wait_for_element_visible(artists_sel.format(c), "xpath") chart_positions_el = self.wait_for_element_visible(chart_positions_sel.format(c), "xpath") weeks = self.get_text(element=weeks_el) if weeks == "": ActionChains(self.driver).move_to_element(to_element=weeks_el).perform() weeks = self.get_text("//*[text()='Re-Entry' or text()='New Entry']", "xpath") trend_el = self.wait_for_element_visible(trend_sel.format(c), "xpath") streams_el = self.wait_for_element_visible(streams_sel.format(c)) streams_trend_el = self.wait_for_element_visible(streams_trend_sel.format(c)) track_el = self.wait_for_element_visible(track_name_sel.format(c), "xpath") track = self.get_text(element=track_el) track_el = self.wait_for_element_visible(track_id_loc.format(c), "xpath") track_id = track_el.get_attribute("href").split("/")[-1] artists = self.get_text(element=artists_el) chart_position = self.get_text(element=chart_positions_el) trend = str(self.get_text(element=trend_el)).strip() streams = int(self.get_text(element=streams_el).replace(",", "")) streams_trend = str(self.get_text(element=streams_trend_el)).replace("%", "") track = {track: {"artists": artists, "weeks": weeks, "chart_position": chart_position, "track_id": track_id, "trend": trend, "index": c, "streams": streams, "streams_trend": streams_trend}} data.update(track) self.log.info(f"tab: {tab_name} - table gtp data: {data}") return data @allure.step("GTP - verify chart icon present in table for track index") def verify_chart_icon(self, index, present=True): icon_sel = f"(//*[contains(@id, 'chart-position-')]//../*[contains(@class, 'icon-chart-position-m')])[{index}]" icon = self.is_element_displayed(icon_sel, "xpath") assert_that(icon).is_equal_to(present) @allure.step("GTP - verify blue dot trend icon present") def verify_blue_dot_trend(self, index, present=True): trend_dot_sel = f"//*[contains(@id, 'position-trend-{index}')]//../*[contains(@class, 'icon-chart-circle')]" dot = self.is_element_displayed(trend_dot_sel, "xpath") assert_that(dot).is_equal_to(present) @allure.step("GTP - verify streams trend hover tooltip") def verify_streams_trend_hover(self, market, streams_date, index=1): trend_sel = f"//*[@id='gtp-table-cell-streams-trend-{index}']/..//*[@tag][contains(., '%')]" self.hover_on_element(trend_sel, "xpath") tooltip = self.get_text(self.trackPage.hint_locator, "xpath").replace("\n", "").replace(",", "") tab_data = self.get_all_from_table() first_track = list(tab_data.keys())[index - 1] id = tab_data[first_track]["track_id"] isrc = self.api_client.get_isrc_by_spotify_id(market, id)["external_ids"]["isrc"] streams_api_resp = self.api_client.get_gtp_streams(isrcs=[isrc], market=market, date=streams_date)[0]["data"] streams_api = [s["streams"] for s in streams_api_resp] dates_api = [datetime.datetime.strptime(str(s["date"]), "%Y-%m-%d").strftime(self.trackPage.get_date_format_from_locale()) for s in streams_api_resp] if len(streams_api) == 2: before_streams = streams_api[0] current_streams = streams_api[1] diff = current_streams - before_streams if diff > 0: trend = "more" else: trend = "less" tooltip_exp = f"{abs(diff)} streams {trend} on {dates_api[1]} than {dates_api[0]}" assert_that(tooltip_exp).is_equal_to(tooltip) @allure.step("GTP - open Hot Hits modal from table") def open_hot_hits_from_table(self, position=1): self.wait_for_element_visible(*self.locator(self.gtp_locators, "table_hothits_icons")) icons = self.get_elements(*self.locator(self.gtp_locators, "table_hothits_icons")) self.scroll_to_element(*self.locator(self.gtp_locators, "table_hothits_icons")) self.wait_for_element_visible(*self.locator(self.gtp_locators, "table_hothits_icons")) self.wait_for_element_clickable(*self.locator(self.gtp_locators, "table_hothits_icons")) self.click_element(element=icons[position - 1]) self.gtp_hhm.is_modal_opened() @allure.step("GTP - verify collapsed datepicker element") def verify_collapsed_datepicker(self, expected_selected_date, location): datepicker = self.wait_for_element_clickable(*self.locator(self.gtp_locators, "date_picker")) is_datepicker_present = self.is_element_displayed(*self.locator(self.gtp_locators, "date_picker")) date_selected = self.get_attribute_value(*self.locator(self.gtp_locators, "date_picker"), attribute="value") date_selected_modified = datetime.datetime.strptime(date_selected, self.trackPage.get_date_format_from_locale()).strftime("%Y-%m-%d") calendar_icon = self.is_element_displayed(*self.locator(self.gtp_locators, "date_picker_calendar_icon")) background_collapsed = datepicker.value_of_css_property("background-color") info_icon = self.is_element_displayed(*self.locator(self.gtp_locators, "date_picker_info_icon")) assert_that(is_datepicker_present).is_true() assert_that(date_selected_modified).is_equal_to(expected_selected_date) assert_that(calendar_icon).is_true() if location == "gtp": assert_that(background_collapsed).is_equal_to(self.DATEPICKER_COLLAPSED_BG_COLOR) elif location == "top_charts": assert_that(background_collapsed).is_equal_to(self.DATEPICKER_COLLAPSED_BG_COLOR) elif location == "nvp_trending": assert_that(background_collapsed).is_equal_to(self.trackPage.YT_TRENDING_DATEPICKER_COLLAPSED_BG_COLOR) elif location == "tt_dashboard": assert_that(background_collapsed).is_equal_to(self.DATEPICKER_COLLAPSED_BG_COLOR) assert_that(info_icon).is_true() @allure.step("GTP - expand datepicker element") def expand_datepicker(self): datepicker = self.wait_for_element_clickable(*self.locator(self.gtp_locators, "date_picker")) self.click_element(element=datepicker) enter_icon = self.is_element_displayed(*self.locator(self.gtp_locators, "date_picker_enter_icon")) assert_that(enter_icon).is_true() @allure.step("GTP - click outside datepicker element") def click_outside_datepicker(self, market): self.trackPage.is_market_in_header_correct(market) header = self.get_element(*self.locator(self.gtp_locators, "page_header")) if "/top-charts" in self.get_url(): header = self.get_element("charts-title") self.click_element(element=header) calender_icon = self.is_element_displayed(*self.locator(self.gtp_locators, "date_picker_calendar_icon")) assert_that(calender_icon).is_true() @allure.step("GTP - reset datepicker") def reset_datepicker(self, expected_default_date): reset_button = self.get_element(*self.locator(self.gtp_locators, "date_picker_reset_button")) self.click_element(element=reset_button) self.wait_for_element_clickable(*self.locator(self.gtp_locators, "date_picker")) selected_date_el = self.get_attribute_value(*self.locator(self.gtp_locators, "date_picker"), attribute="value") selected_date = datetime.datetime.strptime(selected_date_el, self.trackPage.get_date_format_from_locale()).strftime("%Y-%m-%d") calendar_icon = self.is_element_displayed(*self.locator(self.gtp_locators, "date_picker_calendar_icon")) assert_that(calendar_icon).is_true() assert_that(selected_date).is_equal_to(expected_default_date) @allure.step("GTP - verify date month label format") def verify_date_month_format(self): calendar_month_year_locator = "(//div[@class='DayPicker-Caption']/div/div)[2]" calendar_month_year_el = self.get_element(locator=calendar_month_year_locator, locator_type="xpath") calendar_month_year_text = self.get_text(element=calendar_month_year_el) date_selected = self.get_attribute_value(*self.locator(self.gtp_locators, "date_picker"), attribute="value") selected_date_month_year_format = datetime.datetime.strptime(date_selected, self.trackPage.get_date_format_from_locale()).strftime("%b %Y") assert_that(calendar_month_year_text).is_equal_to(selected_date_month_year_format) return calendar_month_year_text @allure.step("GTP - verify collapsed datepicker element") def verify_datepicker_arrows(self): calendar_month_year_locator = "(//div[@class='DayPicker-Caption']/div/div)[2]" prev_years_arrow = self.get_element(*self.locator(self.gtp_locators, "date_picker_year_arrow_backward")) next_years_arrow = self.get_element(*self.locator(self.gtp_locators, "date_picker_year_arrow_forward")) prev_month_arrow = self.get_element(*self.locator(self.gtp_locators, "date_picker_month_arrow_backward")) next_month_arrow = self.get_element(*self.locator(self.gtp_locators, "date_picker_month_arrow_forward")) arrows = [prev_years_arrow, next_years_arrow, prev_month_arrow, next_month_arrow] for arrow in arrows: calendar_month_year_el_before = self.get_element(locator=calendar_month_year_locator, locator_type="xpath") calendar_month_year_text = self.get_text(element=calendar_month_year_el_before) calendar_date_before = datetime.datetime.strptime(calendar_month_year_text, "%b %Y").date() self.click_element(element=arrow) calendar_month_year_el_after = self.get_element(locator=calendar_month_year_locator, locator_type="xpath") calendar_month_year_text = self.get_text(element=calendar_month_year_el_after) calendar_date_after = datetime.datetime.strptime(calendar_month_year_text, "%b %Y").date() if arrow == prev_years_arrow: assert_that(calendar_date_before.year).is_equal_to(calendar_date_after.year + 1) elif arrow == next_years_arrow: assert_that(calendar_date_before.year).is_equal_to(calendar_date_after.year - 1) elif arrow == prev_month_arrow: if calendar_date_after.month == 12: assert_that(calendar_date_before.month).is_equal_to(1) else: assert_that(calendar_date_before.month).is_equal_to(calendar_date_after.month + 1) elif arrow == next_month_arrow: if calendar_date_before.month == 12: assert_that(0).is_equal_to(calendar_date_after.month - 1) else: assert_that(calendar_date_before.month).is_equal_to(calendar_date_after.month - 1) @allure.step("GTP - calendar grid verification") def calendar_default_grid_verification(self, date="", check_dots=True): first_weekday_locator = "(//div[@class='DayPicker-Weekday'])[1]" selected_date_locator = "//*[contains(@class, 'selected')]" grid_mondays_locator = "//div[@class='DayPicker-Day'][contains(@aria-label, 'Mon')]" grid_mondays_pink_dot_locator = "//div[@class='DayPicker-Day'][contains(@aria-label, 'Mon')]/div/div" new_list_release_locator = "//div[contains(text(), 'New List Release')]/parent::div" new_list_release_pink_dot_locator = "//div[contains(text(), 'New List Release')]/preceding-sibling::div" # check grid first weekday is monday weekday_el = self.get_element(locator=first_weekday_locator, locator_type="xpath") weekday_text = self.get_text(element=weekday_el) self.log.info("First weekday " + weekday_text) assert_that(weekday_text).is_equal_to(self.CALENDAR_GRID_FIRST_WEEKDAY) # check grid default selected date is today's date grid_selected_date = self.get_attribute_value(locator=selected_date_locator, locator_type="xpath", attribute="aria-label") grid_selected_date_formatted = datetime.datetime.strptime(grid_selected_date, "%a %b %d %Y").date() self.log.info("Selected date " + str(grid_selected_date_formatted)) if date == "": today_date = datetime.date.today() else: today_date = date assert_that(grid_selected_date_formatted).is_equal_to(today_date) # check all grid mondays have pink dot if check_dots: grid_mondays = self.get_elements(locator=grid_mondays_locator, locator_type="xpath") grid_mondays_pink_dots = self.get_elements(locator=grid_mondays_pink_dot_locator, locator_type="xpath") assert_that(len(grid_mondays)).is_equal_to(len(grid_mondays_pink_dots)) # additional checks new_list_release = self.get_element(locator=new_list_release_locator, locator_type="xpath") new_list_release_text = self.get_text(element=new_list_release) new_list_release_pink_dot = self.is_element_displayed(locator=new_list_release_pink_dot_locator, locator_type="xpath") assert_that(new_list_release_text).is_equal_to("New List Release") assert_that(new_list_release_pink_dot).is_true() reset_button = self.is_element_displayed(*self.locator(self.gtp_locators, "date_picker_reset_button")) assert_that(reset_button).is_true() @allure.step("GTP - check datepicker manual entry field") def check_datepicker_manual_entry_field(self): datepicker = self.get_element(*self.locator(self.gtp_locators, "date_picker")) focused_el = self.driver.switch_to.active_element assert_that(datepicker).is_equal_to(focused_el) @allure.step("GTP - clear date manually") def clear_date_manually(self): self.wait_for_element_clickable(*self.locator(self.gtp_locators, "date_picker")) datepicker = self.get_element(*self.locator(self.gtp_locators, "date_picker")) ActionChains(self.driver).click(on_element=datepicker).send_keys(Keys.BACK_SPACE * 7).perform() datepicker_value = self.get_attribute_value(element=datepicker, attribute="value") assert_that(datepicker_value).is_empty() @allure.step("GTP - verify datepicker empty date") def verify_datepicker_empty_date(self): today_date_locator = "//div[contains(@class, 'DayPicker-Day--today')]" datepicker = self.get_element(*self.locator(self.gtp_locators, "date_picker")) datepicker_placeholder = self.get_attribute_value(element=datepicker, attribute="placeholder") enter_icon_color = self.get_element(*self.locator(self.gtp_locators, "date_picker_enter_icon")).value_of_css_property("color") today_date_color = self.get_element(locator=today_date_locator, locator_type="xpath").value_of_css_property("color") assert_that(datepicker_placeholder).is_equal_to("MM/DD/YY") assert_that(enter_icon_color).is_equal_to(self.DATEPICKER_ENTER_ICON) assert_that(today_date_color).is_equal_to(self.DATEPICKER_TODAY_DATE_COLOR) @allure.step("GTP - verify datepicker arrows background color") def verify_datepicker_arrows_background(self): arrows_locator = "//div[@class='DayPicker-wrapper']//span[contains(@class, 'icon')]/parent::div" arrows = self.get_elements(locator=arrows_locator, locator_type="xpath") datepicker = self.get_element(*self.locator(self.gtp_locators, "date_picker")) prev_year_arrow = self.get_element(*self.locator(self.gtp_locators, "date_picker_year_arrow_backward")) self.click_element(element=prev_year_arrow) ActionChains(self.driver).move_to_element(to_element=datepicker).perform() for arrow in arrows: color_before_hover = arrow.value_of_css_property("background-color") self.log.info("color before hover: {}".format(color_before_hover)) ActionChains(self.driver).move_to_element(to_element=arrow).perform() color_after_hover = arrow.value_of_css_property("background-color") self.log.info("color after hover: {}".format(color_after_hover)) assert_that(color_before_hover).is_not_equal_to(color_after_hover) assert_that(color_after_hover).is_equal_to(self.DATEPICKER_ARROW_HOVER) @allure.step("GTP - verify datepicker arrows swiping to disabled state") def verify_datepicker_swiping_to_unavailable_date(self, date, swipe="backward", year_month="year"): datepicker = self.get_element(*self.locator(self.gtp_locators, "date_picker")) swiping_arrow = self.get_element(*self.locator(self.gtp_locators, "date_picker_{}_arrow_{}".format(year_month, swipe))) date_to_count = datetime.datetime.strptime(date, "%Y-%m-%d").date() selected_date = self.get_datepicker_selected_date() selected_date_formatted = datetime.datetime.strptime(selected_date, "%Y-%m-%d").date() years = abs(selected_date_formatted.year - date_to_count.year) self.log.info("Numer of years: " + str(years)) if selected_date_formatted.day > selected_date_formatted.day: months = rrule.rrule(rrule.MONTHLY, dtstart=date_to_count, until=selected_date_formatted).count() - 1 else: months = rrule.rrule(rrule.MONTHLY, dtstart=date_to_count, until=selected_date_formatted).count() self.log.info("Numer of months: " + str(months)) arrow_color_before = swiping_arrow.value_of_css_property("color") self.log.info("color before: {}".format(arrow_color_before)) if year_month == "month": for m in range(months): self.click_element(element=swiping_arrow) elif year_month == "year": for m in range(years): self.click_element(element=swiping_arrow) arrow_color_after = swiping_arrow.value_of_css_property("color") self.log.info("color after: {}".format(arrow_color_after)) focused_el = self.driver.switch_to.active_element assert_that(datepicker).is_not_equal_to(focused_el) assert_that(arrow_color_before).is_not_equal_to(arrow_color_after) assert_that(arrow_color_after).is_equal_to(self.DATEPICKER_DISABLED_ARROW_COLOR) @allure.step("GTP - verify datepicker swiping to date") def datepicker_swipe_to_date(self, date, swipe="backward"): swiping_arrow = self.get_element(*self.locator(self.gtp_locators, "date_picker_month_arrow_{}".format(swipe))) date_to_count = datetime.datetime.strptime(date, "%Y-%m-%d").date() date_selected_before = self.get_attribute_value(*self.locator(self.gtp_locators, "date_picker"), attribute="value") date_selected = datetime.datetime.strptime(date_selected_before, self.trackPage.get_date_format_from_locale()).date() self.log.info(f"Selected date: {date_selected}") if date_selected.day > date_to_count.day: months = rrule.rrule(rrule.MONTHLY, dtstart=date_to_count, until=date_selected).count() - 1 else: months = rrule.rrule(rrule.MONTHLY, dtstart=date_to_count, until=date_selected).count() self.log.info("Numer of months: " + str(months)) for m in range(months): self.click_element(element=swiping_arrow) calendar_month_year_locator = "(//div[@class='DayPicker-Caption']/div/div)[2]" calendar_month_year_el = self.get_element(locator=calendar_month_year_locator, locator_type="xpath") calendar_month_year_text = self.get_text(element=calendar_month_year_el) date_to_count_month_year = datetime.datetime.strptime(date, "%Y-%m-%d").strftime("%b %Y") assert_that(date_to_count_month_year).is_equal_to(calendar_month_year_text) @allure.step("GTP - verify date not in focus after swiping") def verify_datepicker_datefield_not_in_focus_after_swipe(self, swipe="backward"): datepicker = self.get_element(*self.locator(self.gtp_locators, "date_picker")) swiping_arrow = self.get_element(*self.locator(self.gtp_locators, "date_picker_month_arrow_{}".format(swipe))) self.click_element(element=swiping_arrow) focused_el = self.driver.switch_to.active_element assert_that(datepicker).is_not_equal_to(focused_el) @allure.step("GTP - open datepicker previous month grid") def open_datepicker_prev_month_grid(self): datepicker = self.get_element(*self.locator(self.gtp_locators, "date_picker")) self.click_element(element=datepicker) prev_month_arrow = self.get_element(*self.locator(self.gtp_locators, "date_picker_month_arrow_backward")) self.click_element(element=prev_month_arrow) @allure.step("GTP - enter manually valid datepicker date") def enter_datepicker_date_manually(self, date, location, apply_by="enter"): self.wait_for_element_visible("tiktok-dashboard-table-cell-compare-1") self.wait_for_element_clickable("tiktok-dashboard-table-cell-compare-1") datepicker = self.get_element(*self.locator(self.gtp_locators, "date_picker")) self.click_element(element=datepicker) date_to_enter = datetime.datetime.strptime(date, "%Y-%m-%d").strftime(self.trackPage.get_date_format_from_locale()) self.send_text(data=date_to_enter, element=datepicker) if apply_by == "enter": ActionChains(self.driver).send_keys(Keys.ENTER).perform() time.sleep(5) elif apply_by == "outside": self.global_search.click_beyond_search_field() datepicker_value = self.get_attribute_value(*self.locator(self.gtp_locators, "date_picker"), attribute="value") assert_that(datepicker_value).is_equal_to(date_to_enter) if location == "gtp": url_date = self.trackPage.parameter_from_url(self.hd_date) url_date_formatted = datetime.datetime.strptime(url_date, "%Y-%m-%d").strftime(self.trackPage.get_date_format_from_locale()) assert_that(url_date_formatted).is_equal_to(date_to_enter) elif location == "nvp_trending": url_date = self.trackPage.parameter_from_url(self.trackPage.trending_date) url_date_formatted = datetime.datetime.strptime(url_date, "%Y-%m-%d").strftime(self.trackPage.get_date_format_from_locale()) assert_that(url_date_formatted).is_equal_to(date_to_enter) elif location == "top_charts": url_date = self.trackPage.parameter_from_url("date") url_date_formatted = datetime.datetime.strptime(url_date, "%Y-%m-%d").strftime(self.trackPage.get_date_format_from_locale()) assert_that(url_date_formatted).is_equal_to(date_to_enter) elif location == "tt_dashboard": url_date = self.trackPage.parameter_from_url("date") url_date_formatted = datetime.datetime.strptime(url_date, "%Y-%m-%d").strftime(self.trackPage.get_date_format_from_locale()) assert_that(url_date_formatted).is_equal_to(date_to_enter) @allure.step("GTP - enter manually any value to datepicker") def enter_any_value_to_datepicker_manually(self, value, apply_by="enter"): datepicker = self.get_element(*self.locator(self.gtp_locators, "date_picker")) self.send_text(data=value, element=datepicker) if apply_by == "enter": ActionChains(self.driver).send_keys(Keys.ENTER).perform() time.sleep(5) elif apply_by == "outside": self.global_search.click_beyond_search_field() @allure.step("GTP - verify manually entered valid datepicker date") def verify_datepicker_grid_selected_date(self, expected_selected_date): expected_date = datetime.datetime.strptime(expected_selected_date, "%Y-%m-%d").strftime(self.trackPage.get_date_format_from_locale()) datepicker = self.get_element(*self.locator(self.gtp_locators, "date_picker")) selected_date_locator = "//div[contains(@class, 'DayPicker-Day--selected')]" datepicker_value = self.get_attribute_value(element=datepicker, attribute="value") self.expand_datepicker() selected_date = self.get_element(locator=selected_date_locator, locator_type="xpath") grid_selected_date = self.get_attribute_value(locator=selected_date_locator, locator_type="xpath", attribute="aria-label") grid_selected_date_formatted = datetime.datetime.strptime(grid_selected_date, "%a %b %d %Y").strftime(self.trackPage.get_date_format_from_locale()) assert_that(expected_date).is_equal_to(datepicker_value) assert_that(datepicker_value).is_equal_to(grid_selected_date_formatted) grid_selected_date_color = selected_date.value_of_css_property("color") self.log.info("Selected date color " + str(grid_selected_date_color)) grid_selected_date_background_color = selected_date.value_of_css_property("background-color") self.log.info("Selected date background color " + str(grid_selected_date_background_color)) assert_that(grid_selected_date_color).is_equal_to(self.DATEPICKER_SELECTED_DATE_COLOR) assert_that(grid_selected_date_background_color).is_equal_to(self.DATEPICKER_SELECTED_DATE_BACKGROUND_COLOR) @allure.step("GTP - datepicker grid when no data selected") def verify_datepicker_grid_no_date_selected(self): self.expand_datepicker() grid_dates_locator = "//div[contains(@class, 'DayPicker-Day')][@aria-disabled='false']" grid_dates = self.get_elements(locator=grid_dates_locator, locator_type="xpath") dates_background_list = [] for date in grid_dates: grid_date_background_color = date.value_of_css_property("background-color") dates_background_list.append(grid_date_background_color) self.log.info("Set of dates: " + str(set(dates_background_list))) for date_background in set(dates_background_list): assert_that(date_background).is_not_equal_to(self.DATEPICKER_SELECTED_DATE_BACKGROUND_COLOR) @allure.step("GTP - enter manually invalid datepicker date") def verify_datepicker_invalid_date_manual_entering(self, date, apply_by="enter"): validation_message_locator = "//span[text()='Please enter full date.']" datepicker = self.get_element(*self.locator(self.gtp_locators, "date_picker")) datepicker_value_before = self.get_attribute_value(element=datepicker, attribute="value") self.click_element(element=datepicker) self.clear_date_manually() self.send_text(data=date, element=datepicker) if apply_by == "enter": ActionChains(self.driver).send_keys(Keys.ENTER).perform() time.sleep(5) validation_message = self.get_element(locator=validation_message_locator, locator_type="xpath") validation_message_text = self.get_text(element=validation_message) assert_that(validation_message_text).described_as(date).is_equal_to(self.DATEPICKER_VALIDATION_MESSAGE) elif apply_by == "outside": self.global_search.click_beyond_search_field() datepicker_value_after = self.get_attribute_value(element=datepicker, attribute="value") assert_that(datepicker_value_before).is_equal_to(datepicker_value_after) if "/top-charts" in self.get_url(): url_date = self.trackPage.parameter_from_url("date") else: url_date = self.trackPage.parameter_from_url(self.hd_date) url_date_formatted = datetime.datetime.strptime(url_date, "%Y-%m-%d").strftime(self.trackPage.get_date_format_from_locale()) assert_that(url_date_formatted).described_as(date).is_equal_to(datepicker_value_before) @allure.step("GTP - select date from a datepicker grid") def select_date_from_datepicker_grid(self, date, location, swipe="backward"): grid_date = datetime.datetime.strptime(date, "%Y-%m-%d").strftime("%a %b %d %Y") grid_date_locator = f"//div[@aria-label='{grid_date}']" self.expand_datepicker() self.datepicker_swipe_to_date(date, swipe) grid_date_el = self.get_element(locator=grid_date_locator, locator_type="xpath") date_color_before_hover = grid_date_el.value_of_css_property("color") background_color_before_hover = grid_date_el.value_of_css_property("background-color") ActionChains(self.driver).move_to_element(to_element=grid_date_el).perform() date_color_after_hover = grid_date_el.value_of_css_property("color") self.log.info("Date color after hover: {}".format(date_color_after_hover)) background_color_after_hover = grid_date_el.value_of_css_property("background-color") self.log.info("Background color after hover: {}".format(background_color_after_hover)) assert_that(date_color_before_hover).is_not_equal_to(date_color_after_hover) assert_that(date_color_after_hover).is_equal_to(self.DATEPICKER_HOVERED_DATE_COLOR) assert_that(background_color_before_hover).is_not_equal_to(background_color_after_hover) assert_that(background_color_after_hover).is_equal_to(self.DATEPICKER_HOVERED_DATE_BACKGROUND_COLOR) self.click_element(element=grid_date_el) self.verify_datepicker_grid_selected_date(date) if location == "gtp": url_date = self.trackPage.parameter_from_url(self.hd_date) assert_that(url_date).is_equal_to(date) elif location == "nvp_trending": url_date = self.trackPage.parameter_from_url(self.trackPage.trending_date) assert_that(url_date).is_equal_to(date) elif location == "top_charts": url_date = self.trackPage.parameter_from_url("date") assert_that(url_date).is_equal_to(date) elif location == "tt_dashboard": url_date = self.trackPage.parameter_from_url("date") assert_that(url_date).is_equal_to(date)