import datetime import logging import time from random import randint import allure from assertpy import assert_that from selenium.webdriver import ActionChains 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.src.pages.global_track_priorities_page import GlobalTrackPrioritiesPage from app.src.pages.track_page import TrackPage from app.src.pages.tt_dashboard_page import TTDashboardPage class TTDashboardPOTPopup(BasePage): log = cl.Logger(logging.DEBUG) def __init__(self, driver): super().__init__(driver) self.driver = driver self.tp = TrackPage(self.driver) self.tt_dashboard = TTDashboardPage(self.driver) self.api_client = ApiClient() self.gtp = GlobalTrackPrioritiesPage(self.driver) self.ts = TestStatus(self.driver) @allure.step("TT DashboardPage POT Popup- open") def open(self, index=""): if index == "": index = randint(1, 6) self.log.info(f"index for potp: {index}") loc = f"(//*[contains(@id, 'chart-position-#')])[{index}]" popup_title_loc = "top-charts-over-time-position-tiktok-modal-window-title" popup_icon = self.wait_for_element_clickable(loc, "xpath") self.click_element(element=popup_icon) title_el = self.wait_for_element_visible(popup_title_loc) assert_that(self.is_element_displayed(element=title_el)).is_true() @allure.step("TT DashboardPage POT Popup - verify export button and hover") def verify_export_button_and_hover(self): loc = "tiktok-dashboard-tiktok-modal-window-export-btn" export_el = self.wait_for_element_clickable(loc) color_before = export_el.value_of_css_property("background-color") self.hover_on_element(element=export_el) color_after = export_el.value_of_css_property("background-color") cursor = export_el.value_of_css_property("cursor") assert_that(cursor).is_equal_to("pointer") assert_that(color_before).is_not_equal_to(color_after) @allure.step("TT DashboardPage POT Popup - get track link") def get_track_link_id(self): loc = "tiktok-dashboard-tiktok-modal-window-track-link" link_el = self.wait_for_element_clickable(loc) id = self.get_attribute_value(element=link_el, attribute="href").split("/")[-1] return id @allure.step("TT DashboardPage POTP - verify exported data") def verify_export_data(self, market, default_period=True): loc = "tiktok-dashboard-tiktok-modal-window-export-btn" track_ui = self.get_track_name() no_data = False if not default_period: self.tp.select_previous_mounth_period() no_data = self.is_element_displayed("//*[text()='No data available.']", "xpath") if not no_data: export_el = self.wait_for_element_clickable(loc) self.click_element(element=export_el) tab_url = self.tp.parameter_from_url(self.tt_dashboard.tab) filter_url = self.tp.parameter_from_url(self.tt_dashboard.filter) if tab_url == self.tt_dashboard.bcc: tab = "By Creations Change" type_api = "creations_change" else: tab = "By Creations" type_api = "creations" if filter_url == self.tt_dashboard.daily: filter = "Daily" days_api = 1 else: filter = "7 Days" days_api = 7 file_path = f"""http://{CoreConfig.SELENOID_HOST}:4444/download/{self.driver.session_id}/Position over time - {tab} - {filter} - {track_ui} - {market}.csv""" self.log.info(f"file path: {file_path}") data = self.tp.read_from_csv(file_path) self.log.info(f"pandas data: {data}") columns = [date, country, track_title, position] = ["Date", "Country", "Track Title", "Position"] assert_that(list(data.keys())).is_equal_to(columns) file = {} for c in columns: file[c] = data.get(c).dropna().to_list() self.log.info(f"file: {file}") start = self.tp.get_calendar_start_date() start = datetime.datetime.strptime(start, "%Y-%m-%d").date() end = self.tp.get_calendar_end_date() end = datetime.datetime.strptime(end, "%Y-%m-%d").date() date_range = [] days_count = self.tp.graph_get_count_days_from_calendar() for i in range(days_count): d = start + datetime.timedelta(days=i) date_range.append(str(d)) id = self.get_track_link_id() isrc = self.api_client.get_isrc_by_spotify_id("_gl", id)["external_ids"]["isrc"] market_url = self.tp.parameter_from_url(self.tt_dashboard.market).replace("_gl", "worldwide_no_asian") api_resp = self.api_client.get_tiktok_charts_tracks_cpot(isrc=isrc, start=start, end=end, market=market_url, days=days_api, type=type_api) positions_api = [i["value"] for i in api_resp["items"]] file_date_range = [datetime.datetime.strptime(f, self.tp.get_date_format_from_locale()).strftime("%Y-%m-%d") for f in file[date]] assert_that(file_date_range).is_equal_to(date_range) assert_that(set(file[country])).is_equal_to({market}) assert_that(set(file[track_title])).is_equal_to({track_ui}) assert_that(file[position]).is_equal_to(positions_api) @allure.step("TT DashboardPage POTP - verify icon hover") def verify_icon_hover(self): loc = "(//*[contains(@id, 'chart-position-#')])[1]" icon_el = self.wait_for_element_visible(loc, "xpath") cursor = icon_el.value_of_css_property("cursor") assert_that(cursor).is_equal_to("pointer") @allure.step("TT DashboardPage POTP - verify elements") def verify_elements(self): loc_ids = [ "top-charts-over-time-position-tiktok-modal-window-title", "tiktok-dashboard-tiktok-modal-window-track-link", "tiktok-dashboard-tiktok-modal-window-artist-link", "tiktok-dashboard-tiktok-modal-window-modal-window-day-picker", "tiktok-dashboard-tiktok-modal-window-export-btn", "tiktok-dashboard-tiktok-modal-window-day-count-label", "top-charts-tiktok-modal-window-chart-chart", "top-charts-tiktok-modal-window-chart-legend-count", ] for loc in loc_ids: el = self.wait_for_element_visible(loc) assert_that(self.is_element_displayed(element=el)).described_as(loc).is_true() @allure.step("TT DashboardPage POTP - verify track hover and link") def verify_track_name_link_hover(self): loc = "tiktok-dashboard-tiktok-modal-window-track-link" tooltip_loc = "//*[contains(@id, 'track-tooltip')]" track_el = self.wait_for_element_clickable(loc) track_text = self.get_text(element=track_el) self.hover_on_element(element=track_el) tooltip_text = self.get_text(tooltip_loc, "xpath") assert_that(track_text).is_equal_to(tooltip_text) assert_that(self.get_attribute_value(element=track_el, attribute="href")).contains("/spotify/track/") @allure.step("TT DashboardPage POTP - get list name") def get_list_name(self): loc = "//*[contains(@class, 'icon-tiktok')]/parent::*/following-sibling::*[contains(text(), '(')]" list_el = self.wait_for_element_visible(loc, "xpath") return self.get_text(element=list_el) @allure.step("TT DashboardPage POTP - verify artist link") def verify_artist_link(self): loc = "//*[@id='tiktok-dashboard-tiktok-modal-window-artist-link']//../a" artist_el = self.wait_for_element_clickable(loc, "xpath") assert_that(self.get_attribute_value(element=artist_el, attribute="href")).contains("/spotify/artist/") @allure.step("TT DashboardPage POTP - close popup") def close(self): loc = "top-charts-over-time-position-tiktok-modal-window-close-icon" tt_page_title_loc = "//*[text()='Sony TikTok Toplists']" icon = self.wait_for_element_clickable(loc) self.click_element(element=icon) title_ttp = self.wait_for_element_visible(tt_page_title_loc, "xpath") assert_that(self.is_element_displayed(element=title_ttp)).is_true() @allure.step("TT DashboardPage POTP - verify axes and legend") def verify_axis_and_legend(self): axes_loc = "//*[contains(@class, 'highcharts') and contains(@class, 'title')][string-length(text()) > 0]" legend_locs = ["top-charts-tiktok-modal-window-chart-legend-title", "top-charts-tiktok-modal-window-chart-legend-count", "top-charts-tiktok-modal-window-chart-0-peak-label", "top-charts-tiktok-modal-window-chart-0-min-label"] icon_locs = ["top-charts-tiktok-modal-window-chart-0-peak-icon", "top-charts-tiktok-modal-window-chart-0-min-icon"] self.wait_for_element_visible(axes_loc, "xpath") axes_text = [self.get_text(element=a) for a in self.get_elements(axes_loc, "xpath")] legend_text = [self.get_text(a) for a in legend_locs] assert_that(axes_text).is_equal_to(["POSITION ON LIST", "DATE"]) assert_that(legend_text).is_equal_to(["POSITION", "ON LIST", "Peak", "Minimum"]) for icon in icon_locs: el = self.wait_for_element_visible(icon) assert_that(self.is_element_displayed(element=el)).described_as(icon).is_true() @allure.step("TT DashboardPage POTP - get tooltip") def get_tooltip(self): param = self.tp.graph_get_count_days_from_calendar() selector = "//*[contains(@class, 'highcharts-plot-background')]" self.tp.is_graph_period_displayed() e = self.wait_for_element_visible(selector, "xpath") height = int(e.size["height"]) width = int(e.size["width"]) + 1 self.log.info("height: {height}, width: {width}".format(height=height, width=width)) step = int(width / param) self.log.info("step: {step}".format(step=step)) tooltip = "" for t in range(0, width, step): if len(tooltip) < 1: e = self.wait_for_element_visible(selector, "xpath") # e = self.wait_for_element_clickable(selector, "xpath") ActionChains(self.driver).move_to_element_with_offset(to_element=e, xoffset=t, yoffset=height).perform() t_el = self.wait_for_element_visible(self.tp.hint_locator, "xpath") if t_el is not None: t_el = self.get_text(element=t_el) text = str(t_el) if text not in [None, "None", ["None"], [None], ""]: assert_that("Position" in text).described_as(text).is_true() assert_that(" of 50 tracks" in text).described_as(text).is_true() if text.strip() not in tooltip: tooltip = {"date": datetime.datetime.strptime(text.split(", ")[1].split("\n")[0], self.tp.get_date_format_from_locale()).date(), "position": int(text.split("Position")[1].split(" ")[0].lower().replace("\n", "").replace("peak", "").replace("minimum", ""))} self.log.info("tooltip text: {}".format(text)) self.log.info("tooltip content: {}".format(tooltip)) return tooltip @allure.step("TT DashboardPage POTP - get track name") def get_track_name(self): track_link_loc = "tiktok-dashboard-tiktok-modal-window-track-link" return self.get_text(track_link_loc) @allure.step("TT DashboardPage POTP - get artist name") def get_artist_name(self): loc = "tiktok-dashboard-tiktok-modal-window-artist-link" return self.get_text(loc) @allure.step("TT DashboardPage POTP - verify period selector label") def verify_period_selector_label(self): locs = ["//*[@tag and text()='period']", "//*[@id='tiktok-dashboard-tiktok-modal-window-modal-window-day-picker-icon']"] for loc in locs: assert_that(self.is_element_displayed(loc, "xpath")).described_as(loc).is_true() @allure.step("TT DashboardPage POTP - verify calendar hover") def verify_calendar_hover(self): loc = "//*[contains(@id, 'window-day-picker-icon')]" calendar_el = self.get_element(loc, "xpath") cursor = calendar_el.value_of_css_property("cursor") assert_that(cursor).is_equal_to("pointer") @allure.step("TT DashboardPage POTP - popup select previous month period") def graph_verify_predefined_periods(self): count_label_loc = "tiktok-dashboard-tiktok-modal-window-day-count-label" self.tp.graph_get_xaxis() for p, d in zip(self.tp.dp_predefined_periods, self.tp.dp_predefined_count_days): xaxis_before = self.tp.graph_get_xaxis() days_count_before = self.get_text(count_label_loc) self.tp.select_predefined_period(p) days_count_after = self.get_text(count_label_loc) xaxis_after = self.tp.graph_get_xaxis() assert_that(days_count_before).is_equal_to(days_count_after) assert_that(xaxis_before).is_not_equal_to(xaxis_after) @allure.step("TT DashboardPage POTP - verify datepicker current and future dates") def verify_datepicker_dates(self): today_date_locator = "(//div[contains(@class, 'DayPicker-Day--today')])[last()]" tomorrow_date_locator = today_date_locator + "/following-sibling::div[contains(@class, 'disabled')][1]" today_date_color = self.wait_for_element_visible(locator=today_date_locator, locator_type="xpath").value_of_css_property("color") assert_that([self.gtp.DATEPICKER_TODAY_DATE_COLOR, "rgba(255, 255, 255, 1)"]).contains(today_date_color) today = int(self.get_text(today_date_locator, "xpath")) if today < 28: tomorrow = int(self.get_text(tomorrow_date_locator, "xpath")) assert_that(tomorrow).is_equal_to(today + 1) @allure.step("TT DashboardPage POTP - click on date picker") def click_on_date_picker(self): loc = "//*[contains(@id, 'window-day-picker-icon')]" time.sleep(2) el = self.get_element(loc, "xpath") self.click_on_element_js(element=el) time.sleep(2) @allure.step("TT DashboardPage POTP - verify date picker start, end color and predefined period hover") def verify_datepicker_start_end_hover(self): predef_loc = "//*[contains(@id, 'day-picker-2-weeks')]" first_day_loc = "//*[contains(@class, 'firstDate')]" last_day_loc = "//*[contains(@class, 'lastDate')]" color_before = self.get_element(predef_loc, "xpath").value_of_css_property("background-color") self.hover_on_element(predef_loc, "xpath") color_after = self.get_element(predef_loc, "xpath").value_of_css_property("color") for loc in [first_day_loc, last_day_loc]: assert_that(self.get_element(loc, "xpath").value_of_css_property("color")).described_as(loc).is_equal_to("rgba(255, 255, 255, 1)") assert_that(color_before).is_not_equal_to(color_after) @allure.step("selecting custom period in previous month") def select_previous_mounth_period(self): self.click_on_date_picker() first = self.wait_for_element_visible("(//div[@class='DayPicker-Week']/div[text()='1'])[1]", "xpath") last = self.wait_for_element_visible("(//div[@class='DayPicker-Week']/div[text()='28'])[1]", "xpath") self.click_on_element_js(element=first) self.click_on_element_js(element=last) @allure.step("TT DashboardPage POTP - popup verify days count hint") def popup_calendar_verify_hint(self): count_label_locator = "tiktok-dashboard-tiktok-modal-window-day-count-label" days_count_exp = int(self.get_text(count_label_locator).split(" ")[0]) days = days_count_exp % 7 weeks = days_count_exp // 7 week_part, and_part, day_part = "", "", "" if days == 1: day_part = f"{days} day" elif 1 < days < 7: day_part = f"{days} days" if weeks == 1: week_part = f"{weeks} week" elif weeks > 1: week_part = f"{weeks} weeks" if days_count_exp > 7 and days != 0: and_part = " and " days_in_playlist = self.get_element(count_label_locator) ActionChains(self.driver).move_to_element(to_element=days_in_playlist).perform() tooltip = self.get_text(self.tp.hint_locator, "xpath") assert_that(tooltip).described_as(f"{tooltip},\n {days_count_exp},\n {week_part}{and_part}{day_part}").is_equal_to(f"{week_part}{and_part}{day_part}")