import datetime import logging import time 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.track_page import TrackPage class SpotifyPlaylistPage(BasePage): log = cl.Logger(logging.DEBUG) STREAMS_7_DAYS_AVG = "daily-avg" COLUMN_ARTIST_NAME = "artist-name" SONY = "Sony" NON_SONY = "Non-Sony" filter_input_clear_icon_locator = "spotify-playlist-filter-input-close-icon" def __init__(self, driver): super().__init__(driver) self.driver = driver self.spotify_playlist_page = self.get_page_locators("SpotifyPlaylistPage", "spotify_playlist_elements.json") self.trackPage = TrackPage(self.driver) self.api_client = ApiClient() self.ts = TestStatus(self.driver) @allure.step("Navigating to the specified spotify playlist page") def open_spotify_playlist_page(self, id): self.driver.get("{core_url}/spotify/playlist/{playlist_id}".format(core_url=CoreConfig.ENV_BASE_URL, playlist_id=id)) @allure.step("Spotify playlist page - get selected market") def get_selected_market(self): self.wait_for_element_visible(*self.locator(self.spotify_playlist_page, "market_switcher")) element = self.get_element(*self.locator(self.spotify_playlist_page, "market_switcher")) return str(self.get_text(element=element)) @allure.step("Spotify playlist page - change market") def change_market(self, name): self.trackPage.select_market(name) @allure.step("Spotify playlist page - get values from column") def get_values_from_column(self, column): self.scroll_to_track_details() if column == self.STREAMS_7_DAYS_AVG: loc = f"//*[contains(@id, '{column}-')]/*/*" else: loc = f"//div[contains(@id, '{column}-')]" elements = self.get_elements(locator=loc, locator_type="xpath") values = [self.get_text(element=e) for e in elements] if column in [self.STREAMS_7_DAYS_AVG]: values = [int(str(v).replace(",", "")) for v in values] self.log.info(f"column {column} values: {values}") return values @allure.step("Spotify playlist page - scroll to track details") def scroll_to_track_details(self): self.scroll_to_element(*self.locator(self.spotify_playlist_page, "track_details_header")) @allure.step("Spotify playlist page - get calendar period") def get_chosen_period(self): self.scroll_to_element(*self.locator(self.spotify_playlist_page, "day_picker")) dates = self.get_text(*self.locator(self.spotify_playlist_page, "day_picker")) f = datetime.datetime.strptime(dates.split("–")[0], "%d/%m/%y").strftime("%Y-%m-%d") l = datetime.datetime.strptime(dates.split("–")[1], "%d/%m/%y").strftime("%Y-%m-%d") return {"start": f, "end": l} @allure.step("Spotify playlist page - sort by column") def sort_by_column(self, column_header): self.scroll_to_track_details() self.click_element(f"spotify-playlist-details-tracks-table-cell-{column_header}") @allure.step("Spotify playlist page - switch to worldwide streams") def switch_to_ww_streams(self, ww=True): self.scroll_to_track_details() if ww: tab = "worldwide" else: tab = "market" loc = f"spotify-playlist-details-tracks-scope-bar-{tab}" self.click_element(locator=loc) @allure.step("Spotify playlist page - get playlist title") def get_playlist_title(self): playlist_title = self.get_element(*self.locator(self.spotify_playlist_page, "playlist_title")) playlist_title = self.get_text(element=playlist_title) self.log.info("Playlist title is " + playlist_title) return playlist_title @allure.step("Get playlist id from url") def get_playlist_id_from_url(self): url = self.get_url() playlist_id = url.split("/")[-1] return playlist_id @allure.step("Spotify playlist page - get playlist title") def playlist_title_is_present(self): self.wait_for_element_visible(*self.locator(self.spotify_playlist_page, "playlist_title")) playlist_title = self.get_element(*self.locator(self.spotify_playlist_page, "playlist_title")) self.ts.markFinal(playlist_title, "playlist title is present") @allure.step("Spotify playlist page - filter tracks by sony non-sony type") def playlist_filter_tracks(self, param): filter_dd = self.wait_for_element_clickable(*self.locator(self.spotify_playlist_page, "filter_sony_non-sony_dd")) self.click_element(element=filter_dd) value_locator = f"//div[text()='{param}']" value = self.get_element(locator=value_locator, locator_type="xpath") self.click_element(element=value) dd_value = self.get_text(element=filter_dd) self.log.info("DD value: " + dd_value) @allure.step("Spotify playlist page - top header - get percetages") def get_percentages(self): loc = "//*[contains(@class, 'highcharts-title') and contains(., '%')]" self.wait_for_element_visible(loc, "xpath") els = self.get_elements(loc, "xpath") values = [int(self.get_text(element=e).replace("%", "")) for e in els] assert_that(values).is_length(3) return {"sony": values[0], "frontline": values[1], "local": values[2]} @allure.step("Spotify playlist page - calculate local tracks percentage") def get_local_tracks_percentage_api(self, id, country): resp = self.api_client.get_sony_tracks_analyze_spotify(id, country)["tracks"] self.log.info(f"response: {resp}") local_isrcs = [] for id in resp: if (country == "us") and (str(id["isrc"])[:2] in ["US", "QM", "QZ"]): local_isrcs.append(id["isrc"]) elif (country == "gb") and (str(id["isrc"])[:2] in ["UK", "GB"]): local_isrcs.append(id["isrc"]) elif (country == "br") and (str(id["isrc"])[:2] in ["BR", "BX"]): local_isrcs.append(id["isrc"]) elif (country == "fr") and (str(id["isrc"])[:2] in ["FR", "FX"]): local_isrcs.append(id["isrc"]) elif country == str(str(id["isrc"])[:2]).lower(): local_isrcs.append(id["isrc"]) self.log.info('local isrc" {}'.format(local_isrcs)) percentage = self.trackPage.apply_rounding_percentage(len(local_isrcs) / len(resp) * 100) self.log.info("percentage: {}".format(percentage)) return percentage @allure.step("Spotify playlist page - calculate frontline tracks percentage") def get_frontline_tracks_percentage_api(self, id, country): resp = self.api_client.get_sony_tracks_analyze_spotify(id, country)["tracks"] dates = [] for id in resp: dates.append(datetime.datetime.strptime(id["albumReleaseDate"], "%Y-%m-%d").date()) less_than_30_m = [] for d in dates: self.log.info("date: {}".format(d)) if (datetime.datetime.today().date() - d).days < 913: less_than_30_m.append(d) self.log.info("count less than 30m: {}".format(len(less_than_30_m))) self.log.info("count of all: {}".format(len(dates))) percentage = self.trackPage.apply_rounding_percentage(len(less_than_30_m) / len(dates) * 100) self.log.info("percentage: {}".format(percentage)) return percentage @allure.step("Spotify playlist page - calculate sony tracks percentage") def get_sony_tracks_percentage_api(self, id, country): resp = self.api_client.get_sony_tracks_analyze_spotify(id, country)["tracks"] sony_tracks_count = 0 for id in resp: if id["isSony"]: sony_tracks_count += 1 self.log.info(f"sony tracks count: {sony_tracks_count}\n len resp: {len(resp)}") percentage = self.trackPage.apply_rounding_percentage(sony_tracks_count / len(resp) * 100) return percentage @allure.step("Spotify playlist page - details - scroll down") def table_scroll_down(self): loc = "(//*[contains(@id, 'cell-rank-')])[last()]" self.scroll_to_element(loc, "xpath") @allure.step("Spotify playlist page - verify sticky header") def verify_sticky_header(self, current=True): loc = "//*[@id='spotify-playlist-details-tracks-table-header']//../span[text()]" loc_back = "spotify-playlist-back-to-top" els = self.get_elements(loc, "xpath") texts = [self.get_text(element=e) for e in els] assert_that(self.is_element_displayed(loc, "xpath")).is_true() assert_that(self.is_element_displayed(loc_back)).is_true() if current: assert_that(texts).is_equal_to(["#", "Track", "Release Date", "In Playlist", "Days", "Position", "Current", "Position", "Trend", "Streams", "7 Days, Avg", "Streams", "Index"]) @allure.step("Spotify playlist page - click back to top button") def click_back_to_top(self): loc = "spotify-playlist-back-to-top" self.click_element(loc) @allure.step("Spotify playlist page - is title displayed") def is_title_displayed(self): track_title = "//*[contains(@id, 'playlist-page-info-title-')]" title = self.wait_for_element_visible(track_title, "xpath") assert_that(self.is_element_displayed(element=title)).is_true() @allure.step("Spotify playlist page - track list choose date") def tl_choose_date(self, param): date_to_choose = f"//*[contains(text(), '{param}, ')]" dd_loc = "spotify-playlist-details-tracks-dd-tracklist" self.scroll_to_element(dd_loc, "id") self.click_element(dd_loc, "id") self.click_on_element_js(self.get_element(date_to_choose, "xpath")) @allure.step("Spotify playlist page - verify filter diaplyed") def verify_filter_displayed(self): loc = "//*[@id='spotify-playlist-filter-input' and @placeholder='Filter']" filter_el = self.get_element(loc, "xpath") assert_that(self.is_element_displayed(element=filter_el)).is_true() ActionChains(self.driver).move_to_element(to_element=filter_el).click().pause(2).release().perform() @allure.step("Spotify playlist page - clear filter input") def filter_clear(self): self.click_element(self.filter_input_clear_icon_locator) @allure.step("Spotify playlist page - clear filter icon displayed") def filter_clear_icon_displayed(self): assert_that(self.is_element_displayed(self.filter_input_clear_icon_locator)).is_true() @allure.step("Spotify playlist page - filter tracklist") def tracklist_filter(self, param): self.scroll_to_track_details() loc = "spotify-playlist-filter-input" filter_input = self.get_element(loc) self.send_text(data=param, element=filter_input) time.sleep(0.5) @allure.step("Spotify playlist page - get ids for track name") def get_spotify_ids(self): loc = "//*[contains(@id, 'artist-name-')]/..//a[contains(@href, '/track/')]" els = self.get_elements(loc, "xpath") ids = [self.get_attribute_value(element=e, attribute="href").split("/")[-1] for e in els] self.log.info(f"Tracks id {ids}") return ids @allure.step("Spotify playlist page - click on title") def click_title(self): loc = "playlist-page-info-owner-spotify" self.click_element(loc) @allure.step("Spotify playlist page - verify no data") def verify_no_data(self): loc = "//*[text()='No results to show.']" assert_that(self.is_element_displayed(loc, "xpath")).is_true() @allure.step("Spotify playlist page - is playlist personalized") def is_playlist_personalized(self): loc = "status-bar-label-false-container" assert_that(self.is_element_displayed(loc)).is_true()