import datetime import logging import time import allure import selenium.webdriver from assertpy import assert_that 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 AppConfig, 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.left_navigation_panel import LeftNavigationPanel from app.src.pages.track_page import TrackPage class TTDashboardPage(BasePage): log = cl.Logger(logging.DEBUG) tt_dashboard_link = "Sony TikTok Toplists" tab = "tab" filter = "filter" market = "market" date_dd = "tiktok-dashboard-date-dd-period-dd" date = "date" bcc = "bcc" bc = "bc" daily = "daily" days7 = "7days" by_creations = "by-creations" by_creations_change = "by-creations-change" view_locator = "tiktok-dashboard-scope-bar-{}" tab_locator = "tiktok-dashboard-tab-tiktok{}-tab" market_locator = "tiktok-dashboard-market-dd" column_index = "index" column_image_cover = "image-cover" column_creations_rank = "creations-rank" column_track_name = "track-name" column_track_artist_name = "track-artist-name" column_current_creations = "current-creations" column_creations_trend = "creations-trend" column_creations_trend_weekly = "creations-trend-weekly" column_top_markets = "top-markets" column_days_on_list = "days-on-list" EXPORT_BTN_BACKGROUND_COLOR = "rgba(255, 198, 25, 1)" def __init__(self, driver): super().__init__(driver) self.driver = driver self.tt_dashboard_locators = self.get_page_locators("TTDashboardPage", "tt_dashboard_elements.json") self.left_panel = LeftNavigationPanel(self.driver) self.tp = TrackPage(self.driver) self.api_client = ApiClient() self.sql_client = MySqlClient() self.ts = TestStatus(self.driver) @allure.step("TT DashboardPage - open page") def open(self): self.left_panel.open_right_hamburger_menu_pages(self.tt_dashboard_link) page_header = self.wait_for_element_visible("//*[@tag][text()='Sony TikTok Toplists']", "xpath") assert_that(self.is_element_displayed(element=page_header)).is_true() @allure.step("TT DashboardPage - get selected date on UI") def get_selected_date_ui(self): loc = "//input[contains(@class, 'singlePicker')]" icon_locator = "//*[contains(@class, 'icon-calendar')]" date_el = self.wait_for_element_visible(loc, "xpath") date = self.get_attribute_value(element=date_el, attribute="value") assert_that(self.is_element_displayed(icon_locator, "xpath")).is_true() return date @allure.step("TT DashboardPage - change market") def change_market(self, param): self.wait_for_element_visible("tiktok-dashboard-table-cell-compare-1") self.wait_for_element_clickable("tiktok-dashboard-table-cell-compare-1") self.wait_for_element_visible(self.market_locator) market_current = self.get_market_ui() if market_current != param: self.click_element(self.market_locator) market_item = "//*[contains(@id, 'tiktok-dashboard-market-dd-item')][text()='{}']".format(param) market_item = self.get_element(market_item, "xpath") self.click_on_element_js(market_item) @allure.step("TT DashboardPage - change view") def select_view(self, param): view_el = self.wait_for_element_clickable(self.view_locator.format(param)) self.click_element(element=view_el) self.verify_selected_view(param) @allure.step("TT DashboardPage - change tab") def select_tab(self, param): view_el = self.wait_for_element_clickable(self.tab_locator.format(param)) self.click_element(element=view_el) self.verify_selected_tab(param) @allure.step("TT DashboardPage - verify selected tab") def verify_selected_tab(self, param): self.tp.is_tab_selected(self.tab_locator.format(param)) @allure.step("TT DashboardPage - verify selected view") def verify_selected_view(self, param): self.tp.is_tab_selected(self.view_locator.format(param)) @allure.step("TT DashboardPage - get selected market UI") def get_market_ui(self): market_el = self.wait_for_element_visible(self.market_locator) market = self.get_text(element=market_el) return market @allure.step("TT DashboardPage - verify title") def verify_title_and_hover(self): title_locator = "//*[@tag][.='Sony TikTok Toplists']" beta_locator = "//*[@tag][.='beta']" assert_that(self.is_element_displayed(title_locator, "xpath")).is_true() assert_that(self.is_element_displayed(beta_locator, "xpath")).is_true() self.hover_on_element(beta_locator, "xpath") tooltip = self.get_text(self.tp.hint_locator, "xpath") assert_that(tooltip).is_equal_to( """Please be aware: All TikTok data on Apollo is currently in a "beta" state. The daily numbers are still valuable in identifying trends, but exact daily numbers are being over-reported due to a bug on the TikTok side. It's primarily happening with songs that have both a clean and explicit version. Once TikTok resolves the issue, the Data Strategy team will send an update. For any questions, please email dataanalytics@sonymusic.com.""" ) self.hover_on_element(title_locator, "xpath") @allure.step("TT DashboardPage - verify notice") def verify_notice(self): notice_locator = "tiktok-dashboard-tab-tiktok-text-tab" notice_el = self.wait_for_element_visible(notice_locator) notice = self.get_text(element=notice_el) assert_that(notice).is_equal_to( """Toplists are compiled by SME based on data from TikTok. It is not an official TikTok chart.""" ) @allure.step("TT DashboardPage - verify 'i' icon and hover") def verify_i_icon_and_hover(self): icon_locator = "tiktok-dashboard-scope-bar-scope-bar-hint-icon" icon_el = self.wait_for_element_visible(icon_locator) self.hover_on_element(element=icon_el) tooltip_text = self.get_text(self.tp.hint_locator, "xpath") assert_that(tooltip_text).is_equal_to("7 days signifies the last 7 complete days of TikTok data. We typically experience a 2-day delay.") @allure.step("TT DashboardPage - verify search UI") def verify_search_and_export_ui(self): input_locator = "//input[@placeholder='Filter']" search_icon_locator = "//*[contains(@id, 'search-icon')]" export_locator = "tiktok-dashboard-scope-bar-export-btn" assert_that(self.is_element_displayed(input_locator, "xpath")).is_true() assert_that(self.is_element_displayed(search_icon_locator, "xpath")).is_true() assert_that(self.is_element_displayed(export_locator)).is_true() @allure.step("TT DashboardPage - get all from table UI") def get_all_from_table(self): # header_or_fail_loc = "(//*[@id='tiktok-dashboard-table-header' or text()='Data failed to load. Try refreshing this page.'])[last()]" # headel_or_fail_el = self.wait_for_element_visible(header_or_fail_loc, "xpath") # if self.get_text(element=headel_or_fail_el) == "Data failed to load. Try refreshing this page.": # assert_that(True).described_as("DATA IN TABLE IS FAILED TO LOAD").is_equal_to(False) # else: header_loc = "//*[@id='tiktok-dashboard-table-header']/*[@id]" self.wait_for_element_visible(header_loc, "xpath") columns = [c.get_attribute("id") for c in self.get_elements(header_loc, "xpath")] columns_headers = [c.replace("tiktok-dashboard-table-cell-", "") for c in columns] + [self.column_track_artist_name] self.log.info(f"column headers: {columns_headers}") column_values = {} if len(self.get_elements("//*[contains(@id, 'tiktok-dashboard-table-cell-index-')]/*", "xpath")) > 0: for c in columns_headers: loc = f"//*[contains(@id, 'tiktok-dashboard-table-cell-{c}-')]/*" if c == self.column_creations_trend: loc = f"//*[contains(@id, 'tiktok-dashboard-table-cell-{c}-') and not(contains(@id, 'ly'))]/*" elif c == self.column_image_cover: loc = f"//img[contains(@id, 'tiktok-dashboard-table-cell-{c}-')]" elif c == self.column_track_name: loc = f"//*[contains(@id, 'tiktok-dashboard-table-cell-{c}-')]/span[1]" elif c == self.column_track_artist_name: loc = f"//*[contains(@id, 'tiktok-dashboard-table-cell-{c}-')]" self.log.info(f"locator for {c}: {loc}") self.wait_for_element_visible(loc, "xpath") if c == self.column_image_cover: values = [self.get_attribute_value(element=v, attribute="src") for v in self.get_elements(loc, "xpath")] else: values = [self.get_text(element=v) for v in self.get_elements(loc, "xpath")] column_values.update({c: values}) self.log.info(f"values for : {c}: {values}") else: assert_that(True).described_as("DATA IN TABLE IS FAILED TO LOAD").is_equal_to(False) self.log.info(f"column values: {column_values}") return column_values @allure.step("TT DashboardPage - scroll down") def scroll_down(self): self.wait_for_element_clickable("tiktok-dashboard-scope-bar-export-btn") selenium.webdriver.ActionChains(self.driver).send_keys("\ue010").perform() selenium.webdriver.ActionChains(self.driver).send_keys("\ue010").perform() self.wait_for_element_visible("tiktok-dashboardback-to-top-button") @allure.step("TT DashboardPage - verify table columns") def verify_table_columns(self): table_header_locator = "//*[@id='tiktok-dashboard-table-header']/*" self.wait_for_element_visible("//*[contains(@id, 'tiktok-dashboard-table-cell-index-')]", "xpath") table_columns_el = self.get_elements(table_header_locator, "xpath") table_columns = [self.get_text(element=t) for t in table_columns_el] if self.tp.is_tab_selected_no_assert("tiktok-dashboard-tab-tiktokby-creations-change-tab") and self.tp.is_tab_selected_no_assert("tiktok-dashboard-scope-bar-7days"): date_ui = self.get_selected_date_ui() date_prev6 = (datetime.datetime.strptime(date_ui, self.tp.get_date_format_from_locale()) - datetime.timedelta(days=6)).date() date_prev7 = (datetime.datetime.strptime(date_ui, self.tp.get_date_format_from_locale()) - datetime.timedelta(days=7)).date() date_prev13 = (datetime.datetime.strptime(date_ui, self.tp.get_date_format_from_locale()) - datetime.timedelta(days=13)).date() date_prev6 = datetime.datetime.strptime(str(date_prev6), "%Y-%m-%d").strftime(self.tp.get_date_format_from_locale()) date_prev7 = datetime.datetime.strptime(str(date_prev7), "%Y-%m-%d").strftime(self.tp.get_date_format_from_locale()) date_prev13 = datetime.datetime.strptime(str(date_prev13), "%Y-%m-%d").strftime(self.tp.get_date_format_from_locale()) assert_that(table_columns[4]).is_equal_to(f"{date_ui}-{date_prev6}\nCreations") assert_that(table_columns[5]).is_equal_to(f"Ranking by Change, vs\n{date_prev7}-{date_prev13}\nCreations") assert_that(["#", "Track", "Ranking\nTrend", "Top 10, 7 Days\nMarkets", "Lifetime\nDays on List"]).is_subset_of(table_columns) @allure.step("TT DashboardPage - verify Top 10 column hover") def verify_top_10_column_hover(self): column_locator = "tiktok-dashboard-table-cell-top-markets" column_el = self.wait_for_element_visible(column_locator) self.hover_on_element(element=column_el) tooltip_text = self.get_text("//*[contains(@id, 'tooltip')]", "xpath") assert_that(tooltip_text).is_equal_to( """Top 10 Markets list compiled by aggregating creations for the past 7 days from the selected date.""" ) @allure.step("TT DashboardPage - get column values") def get_from_column(self, column): loc = f"//*[contains(@id, 'tiktok-dashboard-table-cell-{column}-')]" self.wait_for_element_visible(loc, "xpath") if column == "image-cover": values = [c.get_attribute("src") for c in self.get_elements(loc, "xpath") if c.get_attribute("src") is not None] else: values = [self.get_text(element=v) for v in self.get_elements(loc, "xpath")] self.log.info(f"{column} values: {values}") return values @allure.step("TT DashboardPage - verify track title hover") def verify_track_title_hover(self): loc = "(//a[contains(@id, 'tiktok-dashboard-table-cell-track-name-')])[1]" title = self.wait_for_element_visible(loc, "xpath") cursor = title.value_of_css_property("cursor") title_text = self.get_text(element=title) self.hover_on_element(element=title) tooltip_text = self.get_text(self.tp.hint_locator, "xpath") href = self.get_attribute_value(element=title, attribute="href") assert_that(cursor).is_equal_to("pointer") assert_that(title_text).is_equal_to(tooltip_text) assert_that(href).contains("/spotify/track/") @allure.step("TT DashboardPage - verify artist hover and clickable") def verify_artist(self): loc = "(//*[contains(@id, 'tiktok-dashboard-table-cell-track-artist-name-')]/*/a)[1]" title = self.wait_for_element_visible(loc, "xpath") title_text = self.get_text(element=title) self.hover_on_element(element=title) tooltip_text = self.get_text(self.tp.hint_locator, "xpath") href = title.get_attribute("href") assert_that(tooltip_text).contains(title_text) assert_that(href).contains("/spotify/artist/") @allure.step("TT DashboardPage - verify datepicker clock icon") def verify_datepicker_clock_icon(self, tooltip_date): info_icon = self.get_element(*self.locator(self.tt_dashboard_locators, "datepicker_clock_icon")) ActionChains(self.driver).move_to_element(to_element=info_icon).perform() tooltip_date_formatted = datetime.datetime.strptime(tooltip_date, "%Y-%m-%d").strftime(self.tp.get_date_format_from_locale()) hint = self.get_element(locator=self.tp.hint_locator, locator_type="xpath") hint_text = self.get_text(element=hint).replace("\n", " ") self.log.info("Hint text: " + hint_text) assert_that(hint_text).is_equal_to(f"TikTok data up to {tooltip_date_formatted}.") @allure.step("TT DashboardPage - click on column") def click_on_column(self, column): if column == self.column_creations_trend: loc = f"//*[contains(@id, 'tiktok-dashboard-table-cell-{column}') and not(contains(@id, 'weekly'))]" self.wait_for_element_visible(loc) column = self.wait_for_element_clickable(loc, "xpath") else: loc = f"tiktok-dashboard-table-cell-{column}" self.wait_for_element_visible(loc) column = self.wait_for_element_clickable(loc) time.sleep(2) self.click_element(element=column) time.sleep(2) @allure.step("TT DashboardPage - filter table") def filter_by(self, param): loc = "1" filter_el = self.wait_for_element_clickable(loc) self.send_text(data=param, element=filter_el) @allure.step("TT DashboardPage - verify no data") def verify_no_data(self): loc = "//*[.='No results to show.']" no_data_el = self.wait_for_element_visible(loc, "xpath") assert_that(self.is_element_displayed(element=no_data_el)).is_true() @allure.step("TT DashboardPage - verify export button and hover") def verify_export_button_and_hover(self): loc = "tiktok-dashboard-scope-bar-export-btn" self.wait_for_element_visible(loc) 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 - verify exported data") def verify_export_data(self): loc = "tiktok-dashboard-scope-bar-export-btn" export_el = self.wait_for_element_clickable(loc) self.click_element(element=export_el) date_ui = self.get_selected_date_ui() date_csv = datetime.datetime.strptime(date_ui, self.tp.get_date_format_from_locale()).strftime("%m-%d-%Y") date_api = datetime.datetime.strptime(date_ui, self.tp.get_date_format_from_locale()).strftime("%Y-%m-%d") if self.tp.parameter_from_url(self.tab) == self.bcc: tab = "by creations change" api_type = "creations_change" else: tab = "by creations" api_type = "creations" date_change1 = (datetime.datetime.strptime(date_ui, self.tp.get_date_format_from_locale()) - datetime.timedelta(days=1)).date().strftime(self.tp.get_date_format_from_locale()) date_change7 = (datetime.datetime.strptime(date_ui, self.tp.get_date_format_from_locale()) - datetime.timedelta(days=7)).date().strftime(self.tp.get_date_format_from_locale()) date_change6 = (datetime.datetime.strptime(date_ui, self.tp.get_date_format_from_locale()) - datetime.timedelta(days=6)).date().strftime(self.tp.get_date_format_from_locale()) date_change13 = (datetime.datetime.strptime(date_ui, self.tp.get_date_format_from_locale()) - datetime.timedelta(days=13)).date().strftime(self.tp.get_date_format_from_locale()) filter_ui = self.tp.parameter_from_url(self.filter) if filter_ui == self.daily: days_api = 1 columns = [rank, rank_trend, track, artist, date_creations, change1_creations, change7_creations, top_10_markets, lifetime_days] = [ "Rank #", "Ranking Trend", "Track", "Artist", f"{date_ui} Creations", f"Change, vs {date_change1} Creations", f"Change, vs {date_change7} Creations", "Top 10, 7 Days Markets", "Lifetime Days on List", ] else: days_api = 7 columns = [rank, rank_trend, track, artist, change1_6_creations, change7_13_creations, top_10_markets, lifetime_days] = [ "Rank #", "Ranking Trend", "Track", "Artist", f"{date_ui}-{date_change6} Creations", f"Change, vs {date_change7}-{date_change13} Creations", "Top 10, 7 Days Markets", "Lifetime Days on List", ] filter_ui = "7 days" market_ui = self.get_market_ui() if self.tp.parameter_from_url(self.market) == "_gl": market_api = "worldwide_no_asian" else: market_api = self.tp.parameter_from_url(self.market) file_path = f"""http://{CoreConfig.SELENOID_HOST}:4444/download/{self.driver.session_id}/{date_csv}_TikTok_{market_ui}_{filter_ui} toplist_{tab}.csv""" self.log.info(f"file path: {file_path}") data = self.tp.read_from_csv(file_path) self.log.info(f"pandas data: {data}") 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}") trend_api_resp = self.api_client.get_tiktok_charts_tracks(date=date_api, market=market_api, days=days_api, type=api_type) trend_api_values = [] for t in trend_api_resp: if t["selected"]["position"]["is_new"]: trend_api_values.append("New Entry") elif t["selected"]["position"]["is_re_entry"]: trend_api_values.append("Re-entry") else: trend_api_values.append(str(int(t["selected"]["position"]["trend"]) * -1)) assert_that([int(f) for f in file[rank]]).is_equal_to([i for i in list(range(1, 51))]) assert_that([str(r) for r in file[rank_trend]]).is_equal_to(trend_api_values) assert_that([f.replace('"', "") for f in file[track]]).is_equal_to([t["track"]["name"].replace('"', "") for t in trend_api_resp]) assert_that([t[:2] for t in file[artist]]).is_equal_to([t["track"]["artists"][0]["name"][:2] for t in trend_api_resp]) if filter_ui == self.daily: week_change_api_values = [] for t in trend_api_resp: if t["week"]["change"]["value"]: week_change_api_values.append(t["week"]["change"]["value"]) elif t["selected"]["creations"]: week_change_api_values.append(t["selected"]["creations"]) api_change1_creations = [] for t in trend_api_resp: if t["selected"]["creations"] and t["previous"]["creations"]: api_change1_creations.append(t["selected"]["creations"] - t["previous"]["creations"]) elif t["selected"]["creations"]: api_change1_creations.append(t["selected"]["creations"]) elif t["previous"]["creations"]: api_change1_creations.append(-t["previous"]["creations"]) assert_that(file[date_creations]).is_equal_to([t["selected"]["creations"] for t in trend_api_resp if t["selected"]["creations"]]) assert_that(file[change1_creations]).is_equal_to(api_change1_creations) assert_that(file[change7_creations]).is_equal_to(week_change_api_values) else: api_change7_13_creations = [] for t in trend_api_resp: if t["selected"]["creations"] and t["previous"]["creations"]: api_change7_13_creations.append(t["selected"]["creations"] - t["previous"]["creations"]) elif t["selected"]["creations"]: api_change7_13_creations.append(t["selected"]["creations"]) elif t["previous"]["creations"]: api_change7_13_creations.append(-t["previous"]["creations"]) assert_that(file[change1_6_creations]).is_equal_to([t["selected"]["creations"] for t in trend_api_resp if t["selected"]["creations"]]) assert_that(file[change7_13_creations]).is_equal_to(api_change7_13_creations) assert_that(file[top_10_markets]).is_equal_to([", ".join(sorted(m.upper() for m in t["top_markets"])) for t in trend_api_resp if t["top_markets"]]) assert_that(file[lifetime_days]).is_equal_to([t["days_on_list"] for t in trend_api_resp if t["days_on_list"] is not None]) @allure.step("TP - Youtube verify export inactive") def verify_export_inactive(self): self.wait_for_element_visible("tiktok-dashboard-scope-bar-export-btn") export = self.get_element("tiktok-dashboard-scope-bar-export-btn") color_before = export.value_of_css_property("background-color") assert_that(color_before).is_equal_to("rgba(242, 242, 247, 1)") @allure.step("TT DashboardPage - Verify default search field") def verify_default_tt_search_filter(self): input_field = self.wait_for_element_visible(*self.locator(self.tt_dashboard_locators, "tt_dashboard_filter")) icon = self.get_element(*self.locator(self.tt_dashboard_locators, "tt_dashboard_search_icon")) focused_el = self.driver.switch_to.active_element placeholder = self.get_attribute_value(element=input_field, attribute="placeholder") assert_that(self.is_element_displayed(element=input_field)).is_true() assert_that(self.is_element_displayed(element=icon)).is_true() assert_that(input_field).is_not_equal_to(focused_el) assert_that(placeholder).is_equal_to("Filter") color_before = input_field.value_of_css_property("border") self.click_element(element=input_field) color_after = input_field.value_of_css_property("border") focused_el = self.driver.switch_to.active_element placeholder = self.get_attribute_value(element=input_field, attribute="placeholder") assert_that(input_field).is_equal_to(focused_el) assert_that(self.is_element_displayed(element=input_field)).is_true() assert_that(self.is_element_displayed(element=icon)).is_true() assert_that(placeholder).is_equal_to("Filter") assert_that(color_before).is_not_equal_to(color_after) @allure.step("TT DashboardPage - Enter search value to the search field") def enter_tt_dashboard_search_value(self, text): self.wait_for_element_visible(*self.locator(self.tt_dashboard_locators, "tt_dashboard_filter")) self.clear_text(*self.locator(self.tt_dashboard_locators, "tt_dashboard_filter")) self.send_text(text, *self.locator(self.tt_dashboard_locators, "tt_dashboard_filter")) self.page_has_loaded() @allure.step("TT DashboardPage - Filter clear icon is present") def tt_dashboard_is_filter_clear_icon_present(self): self.wait_for_element_visible(*self.locator(self.tt_dashboard_locators, "tt_dashboard_filter")) is_present = self.is_element_present(*self.locator(self.tt_dashboard_locators, "tt_dashboard_clear_icon")) return is_present @allure.step("TT DashboardPage - Clearing filter by clear icon") def tt_dashboard_clear_filter_text(self): self.wait_for_element_clickable(*self.locator(self.tt_dashboard_locators, "tt_dashboard_clear_icon")) self.click_element(*self.locator(self.tt_dashboard_locators, "tt_dashboard_clear_icon")) @allure.step("TT DashboardPage - Is filter cleared") def tt_dashboard_is_filter_cleared(self): input = self.get_element(*self.locator(self.tt_dashboard_locators, "tt_dashboard_filter")) input_text = input.get_attribute("value") self.log.info("Input text: " + input_text) assert_that(input_text).is_empty() @allure.step("TT DashboardPage - get track names per loaded page") def get_tt_dashboard_track_names_per_page_loaded(self): track_names_locator = "//*[contains(@href, '/spotify/track/') or contains(@id, 'track-name-undefined}')][string-length(.) > 0]" self.wait_for_element_visible(locator=track_names_locator, locator_type="xpath") time.sleep(2) track_names_els = self.get_elements(locator=track_names_locator, locator_type="xpath") track_names_list = [self.get_text(element=e) for e in track_names_els] self.log.info("Track names list: " + str(track_names_list)) return track_names_list @allure.step("TT DashboardPage - get artists names per loaded page") def get_tt_dashboard_artists_names_per_page_loaded(self): artist_names_locator = "//*[contains(@id, 'artist-name')]" self.wait_for_element_visible(locator=artist_names_locator, locator_type="xpath") artists_names_els = self.get_elements(locator=artist_names_locator, locator_type="xpath") artists_names_list = [self.get_text(element=e) for e in artists_names_els] self.log.info("Artist names list: " + str(artists_names_list)) return artists_names_list @allure.step("TT DashboardPage - Check for filtered values in the table") def table_is_filtered_by(self, value): track_names_list = self.get_tt_dashboard_track_names_per_page_loaded() artists_names_list = self.get_tt_dashboard_artists_names_per_page_loaded() tracks_list = list(zip(track_names_list, artists_names_list)) assert_that(tracks_list).is_not_empty() self.log.info("Tracks list " + str(tracks_list)) for n, a in tracks_list: assert_that(f"{n.lower()}{a.lower()}").contains(value.lower()) @allure.step("TT DashboardPage - Filter not in focus") def filter_not_in_focus(self): input_field = self.wait_for_element_visible(*self.locator(self.tt_dashboard_locators, "tt_dashboard_filter")) focused_el = self.driver.switch_to.active_element assert_that(input_field).is_not_equal_to(focused_el) @allure.step("TT DashboardPage - Verify export is enabled") def tt_dashboard_export_is_enabled(self): self.wait_for_element_visible(*self.locator(self.tt_dashboard_locators, "tt_dashboard_export_btn")) export_btn_background = self.get_element(*self.locator(self.tt_dashboard_locators, "tt_dashboard_export_btn")).value_of_css_property("background-color") assert_that(export_btn_background).is_equal_to(self.EXPORT_BTN_BACKGROUND_COLOR) @allure.step("TT DashboardPage - Verify market selector and hover") def verify_market_selector_and_hover(self, market): loc = "tiktok-dashboard-market-dd" filter_input_loc = "tiktok-dashboard-market-dd-filter-input" market_dd_item_loc = "tiktok-dashboard-market-dd-item-{}-label" market_dd = self.wait_for_element_clickable(loc) cursor = market_dd.value_of_css_property("cursor") assert_that(cursor).is_equal_to("pointer") self.click_element(element=market_dd) filter_el = self.wait_for_element_visible(filter_input_loc) item0 = self.get_element(market_dd_item_loc.format(0)) item1 = self.get_element(market_dd_item_loc.format(1)) all_markets = sorted(self.market_dd_get_markets()[1:]) translationTable = str.maketrans("éàèùâêîôûç", "eaeuaeiouc") all_markets = [e.translate(translationTable) for e in all_markets] self.log.info(f"filter markets: {all_markets}") assert_that(self.is_element_displayed(element=filter_el)).is_true() assert_that(int(item0.value_of_css_property("font-weight"))).is_greater_than(int(item1.value_of_css_property("font-weight"))) assert_that(self.get_text(element=item1)).is_equal_to(market) assert_that(all_markets).is_equal_to(AppConfig.get("stations_markets")[1:]) @allure.step("TT DashboardPage - market dd filter by") def market_filter_by(self, param): loc = "tiktok-dashboard-market-dd-filter-input" filter_el = self.wait_for_element_clickable(loc) self.send_text(data=param, element=filter_el) @allure.step("TT DashboardPage - market dd get markets") def market_dd_get_markets(self): all_markets_loc = "//*[contains(@id, 'tiktok-dashboard-market-dd-item-') and contains(@id, 'label')][string-length(text()) > 0]" self.wait_for_element_visible(all_markets_loc, "xpath") time.sleep(2) markets = [self.get_text(element=m) for m in self.get_elements(all_markets_loc, "xpath")] return markets @allure.step("TT DashboardPage - market dd verify no markets placeholder") def market_dd_no_markets(self): loc = "//*[text()='No markets found.']" no_markets_el = self.wait_for_element_visible(loc, "xpath") assert_that(self.is_element_displayed(element=no_markets_el)).is_true() @allure.step("TT DashboardPage - market dd click clear icon") def market_dd_click_clear_icon(self): loc = "tiktok-dashboard-market-dd-filter-input-close-icon" icon_el = self.wait_for_element_clickable(loc) self.click_element(element=icon_el) @allure.step("TT DashboardPage - get flags from column UI") def get_flags_ui(self): loc = "//*[contains(@id, 'tiktok-dashboard-table-cell-top-markets-')]//../*[contains(@id, 'flag-market')]" self.wait_for_element_visible(loc, "xpath") values = [self.get_attribute_value(element=v, attribute="id").split("-")[-1] for v in self.get_elements(loc, "xpath")] values = [list(values[i : i + 2]) for i in range(0, len(values), 2)] return values @allure.step("TT DashboardPage - verify comparison icon") def verify_comparison_icon(self): loc = "(//*[contains(@id, 'tiktok-dashboard-table-cell-compare-')]//../a)[1]" icon_el = self.wait_for_element_visible(loc, "xpath") cursor = icon_el.value_of_css_property("cursor") link = self.get_attribute_value(element=icon_el, attribute="href") assert_that(cursor).is_equal_to("pointer") assert_that(link).contains("/tiktok/comparison/") @allure.step("TT DashboardPage - verify top markets hover") def verify_top_markets_hover(self): flags_ui = self.get_flags_ui()[0] self.hover_on_element("(//*[contains(@id, 'flag-market-')])[1]", "xpath") tooltip = self.get_text(self.tp.hint_locator, "xpath") countries = [self.sql_client.get_market_name_by_country_code(c) for c in flags_ui] assert_that(tooltip).is_equal_to(f"""{", ".join(countries)}, and 8 more.""") @allure.step("TT DashboardPage - verify percentage format") def verify_percentage_format(self): loc = "//*[contains(@id, 'trend-percent')]" tooltip_loc = "//*[contains(@id, 'trend-tooltip')]" self.wait_for_element_visible(loc, "xpath") els = self.get_elements(loc, "xpath")[:10] for el in els: text = self.get_text(element=el).split("%")[0].replace("(", "").replace("N/A", "0").lower() if text[-1] in ["k", "m", "b"]: self.hover_on_element(element=el) tooltip = int(self.get_text(tooltip_loc, "xpath").replace("%", "").replace(",", "")) tooltip_mill = self.tp.millify(tooltip) assert_that(tooltip_mill).described_as(f"{tooltip_mill}, {text}").is_equal_to(int(text[:-1])) else: assert_that(int(text)).described_as(text).is_instance_of(int) @allure.step("TT DashboardPage - verify percentage format") def change_date_to_previous(self, days_count=2): self.get_selected_date_ui() current_date = self.tp.parameter_from_url(self.date) previous_date = str((datetime.datetime.strptime(current_date, "%Y-%m-%d") - datetime.timedelta(days=days_count)).date()) self.tp.change_param_in_url_new(self.date, previous_date) self.get_selected_date_ui() @allure.step("TT DashboardPage - select date") def select_date(self, date): date = datetime.datetime.strptime(date, "%Y-%m-%d").strftime(self.tp.get_date_format_from_locale()) self.click_element(self.date_dd) # self.clear_text(self.date_dd) # ActionChains(self.driver).send_keys(Keys.BACK_SPACE).perform() self.send_text(date, self.date_dd) ActionChains(self.driver).send_keys(Keys.ENTER).perform()