import datetime import logging 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 logger as cl from app.api_client import ApiClient from app.src.pages.login_page import LoginPage from app.src.pages.track_page import TrackPage class NewMusicFridayPage(BasePage): log = cl.Logger(logging.DEBUG) nmf_date = "nmf_date" filter_sony = "sony" filter_non_sony = "non_sony" sort_alphabetical = "Alphabetical" sort_top_markets = "Top Markets" sort_track_position = "Track Position" spotify_track_selector = "//*[contains(@href, '/spotify/track/')]" time_icon_sel = "//*[contains(@class, 'icon-time')][last()]" date_dd_locator = "//*[contains(@class, 'icon-down')]/preceding-sibling::*[contains(text(), '/')]" MARKETS_AMOUNT = 50 def __init__(self, driver): super().__init__(driver) self.driver = driver self.nmf_locators = self.get_page_locators("NewMusicFridayPage", "new_music_friday_elements.json") self.ts = TestStatus(self.driver) self.loginPage = LoginPage(self.driver) self.api_client = ApiClient() self.track_page = TrackPage(self.driver) @allure.step("Page header is present") def header_is_present(self): self.wait_for_element_visible(*self.locator(self.nmf_locators, "header")) header = self.is_element_displayed(*self.locator(self.nmf_locators, "header")) assert_that(header).is_true() @allure.step("NMF - Filter - check uncheck and apply") def filter_check_uncheck(self, filter): filter_dd = self.wait_for_element_visible("new-music-friday-header-filter-dd") self.click_element(element=filter_dd) checkbox = self.get_element(f"new-music-friday-header-filter-dd-checkbox-{filter}") self.click_on_element_js(element=checkbox) apply_btn = self.get_element("//*[contains(@id, 'apply-btn')]", "xpath") self.click_on_element_js(element=apply_btn) @allure.step("NMF - Filter by track owner (sony/non-sony)") def filter_by_sony_non_sony(self, params): filter_dd = self.wait_for_element_visible("new-music-friday-header-filter-dd") self.click_element(element=filter_dd) sony_checkbox_locator = "new-music-friday-header-filter-dd-checkbox-sony" non_sony_checkbox_locator = "new-music-friday-header-filter-dd-checkbox-non_sony" for locator in [sony_checkbox_locator, non_sony_checkbox_locator]: if self.track_page.is_checked(locator=locator, locator_type="id"): element = self.get_element(locator=locator) self.click_on_element_js(element=element) for param in params: checkbox = self.get_element(f"new-music-friday-header-filter-dd-checkbox-{param}") self.click_on_element_js(element=checkbox) apply_btn = self.get_element("//*[contains(@id, 'apply-btn')]", "xpath") self.click_on_element_js(element=apply_btn) @allure.step("NMF - Sort by - and apply") def sort_by(self, sort_by): sort_by_dd_sel = "(//*[text()='Sort By']/following-sibling::*//../*[contains(@class, 'icon')]/preceding-sibling::span)[1]" sort_by_dd = self.wait_for_element_visible(sort_by_dd_sel, "xpath") self.click_element(element=sort_by_dd) item = self.get_element(f"//*[text()='{sort_by}']", "xpath") self.click_on_element_js(element=item) @allure.step("NMF - verify owner") def verify_owner(self, params): filter_dd = self.wait_for_element_visible("new-music-friday-header-filter-dd") self.click_element(element=filter_dd) for p in params: checked = self.get_attribute_value(locator=f"new-music-friday-header-filter-dd-checkbox-{p}", attribute="data-checked") assert_that(checked).is_equal_to("checked") self.click_element(element=filter_dd) @allure.step("NMF - verify sort by") def verify_sort_by(self, param): sort_by_dd_sel = "//*[contains(@class, 'icon-down')]/preceding-sibling::*[not(contains(text(), '/')) and string-length(text()) > 10]" sort_by_dd = self.wait_for_element_visible(sort_by_dd_sel, "xpath") assert_that(self.get_text(element=sort_by_dd)).is_equal_to(param) @allure.step("NMF - verify 404") def verify_404(self): el_404 = self.wait_for_element_visible("//*[contains(@id, 'Icons/404/')]", "xpath") assert_that(self.is_element_displayed(element=el_404)).is_true() @allure.step("NMF - Get get track id") def get_track_id_nmf(self, index=0): tracks_list_locator = "//a[contains(@href, '/spotify/track')]" tracks_list = self.get_elements(locator=tracks_list_locator, locator_type="xpath") track_id = self.get_attribute_value(element=tracks_list[index], attribute="href").split("/")[-1] return track_id @allure.step("NMF - get track data") def get_track_data_nmf_by_id(self, date, market, track_id): nmf_tracks_list = self.api_client.get_tracks_info_nmf(date, market) self.log.info("Number of the tracks: " + str(len(nmf_tracks_list["items"]))) track_keys = ["isrc", "track_id", "track_name", "track_artists", "track_featuring_pl_amount"] track_values = [] for track in range(len(nmf_tracks_list["items"])): if nmf_tracks_list["items"][track]["trackId"] == track_id: track_artists = [] for artist in range(len(nmf_tracks_list["items"][track]["artists"])): track_artists.append(nmf_tracks_list["items"][track]["artists"][artist]["name"]) track_values.append(nmf_tracks_list["items"][track]["isrc"]), track_values.append(nmf_tracks_list["items"][track]["trackId"]), track_values.append(nmf_tracks_list["items"][track]["trackName"]), track_values.append(track_artists) track_values.append(len(nmf_tracks_list["items"][track]["playlists"])) track_data = dict(zip(track_keys, track_values)) self.log.info("Track data: " + str(track_data)) return track_data @allure.step("NMF -scroll to last visible track") def scroll_to_last_visible_track(self): sel_last = f"({self.spotify_track_selector})[last()]" self.wait_for_element_visible(self.spotify_track_selector, "xpath") self.scroll_to_element(sel_last, "xpath") @allure.step("NMF - verify sticky headers") def verify_sticky_headers(self, date, sort_by=sort_top_markets): nmf_dates = self.api_client.get_playlists_summary_nmf()["available_dates"] sticky_filter_selector = "//*[@tag='p']" sticky_columns_selector = "//*[contains(@id, 'sticky-column')]" self.wait_for_element_visible(sticky_filter_selector, "xpath") sticky_filter_el = self.get_elements(sticky_filter_selector, "xpath")[1:4] sticky_filters = [self.get_text(element=s) for s in sticky_filter_el] sticky_columns = self.get_elements(sticky_columns_selector, "xpath")[1:-1] sticky_columns = [self.get_text(element=s) for s in sticky_columns] assert_that(self.is_element_displayed(self.time_icon_sel, "xpath")).is_true() assert_that(datetime.datetime.strptime(date, "%Y-%m-%d").strftime(self.track_page.get_date_format_from_locale())).is_equal_to(sticky_filters[0]) assert_that(f"Sorted by: {sort_by}").is_equal_to(sticky_filters[1]) if date != nmf_dates[0]: assert_that(sticky_filters).is_length(2) else: assert_that("All markets received.").is_equal_to(sticky_filters[2]) assert_that(["Name", "Parameters", "Home", "Markets"]).is_equal_to(sticky_columns) @allure.step("NMF - verify clock icon hover") def verify_clock_icon_hover(self): clock_icon_el = self.wait_for_element_visible(self.time_icon_sel, "xpath") ActionChains(self.driver).move_to_element(to_element=clock_icon_el).perform() time_icon_tooltip = self.get_text("//*[contains(@id, 'tooltip')]", "xpath") last_updated = self.api_client.get_playlists_summary_nmf()["last_updated"] dt_object = datetime.datetime.strptime(last_updated, "%Y-%m-%dT%H:%M:%S.%f").strftime(f"{self.track_page.get_date_format_from_locale()}, %I:%M %p") assert_that(f"NMF data last received: {dt_object}.").is_equal_to(time_icon_tooltip) @allure.step("NMF - verify home market global") def verify_home_market_global(self, index=0): base_sel = f"//span[contains(@id, 'new-music-friday-table-row-{index}-track') and contains(@id, 'market-_gl')]" avg_position_sel = f"//*[contains(@id, 'new-music-friday-table-row-{index}-track') and contains(@id, 'param-avg-value')]" feature_value_sel = f"//*[contains(@id, 'new-music-friday-table-row-{index}-track') and contains(@id, 'featuring-value')]" self.wait_for_element_visible(base_sel, "xpath") avg_position = self.wait_for_element_visible(avg_position_sel, "xpath") market_elements = self.get_elements(base_sel, "xpath") self.hover_on_element(element=market_elements[0]) tooltip_ui = self.get_text("//*[contains(@id, 'tooltip')]", "xpath").replace("\n", "") feature_market = self.get_text(feature_value_sel, "xpath") tooltip_exp = f"Avg. position across {feature_market} markets this track is featured in." url_before = self.get_url() self.click_element(element=market_elements[0]) url_after = self.get_url() assert_that(self.get_text(element=avg_position)).is_equal_to(self.get_text(element=market_elements[0])) assert_that(self.get_text(element=market_elements[-1])).is_equal_to("AVG.") assert_that(tooltip_exp).is_equal_to(tooltip_ui) assert_that(url_before).is_equal_to(url_after) @allure.step("NMF - select date") def select_date_in_date_dd(self, index=0): date_dd = self.get_element(locator=self.date_dd_locator, locator_type="xpath") self.wait_for_element_clickable(locator=self.date_dd_locator, locator_type="xpath") self.click_element(element=date_dd) dates_list_locator = "//div[contains(text(), '/')]" dates_list = self.get_elements(locator=dates_list_locator, locator_type="xpath") self.click_element(element=dates_list[index]) selected_date = datetime.datetime.strptime(str(self.get_text(element=dates_list[index])), self.track_page.get_date_format_from_locale()).strftime("%Y-%m-%d") url_date = self.track_page.parameter_from_url(self.nmf_date) assert_that(selected_date).is_equal_to(url_date) return selected_date @allure.step("NMF - Verify default search field") def verify_default_search_filter(self): input_field = self.wait_for_element_visible(*self.locator(self.nmf_locators, "search_field")) icon = self.get_element(*self.locator(self.nmf_locators, "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("Enter search value to the NMF search field") def enter_nmf_search_value(self, text): self.wait_for_element_visible(*self.locator(self.nmf_locators, "search_field")) self.clear_text(*self.locator(self.nmf_locators, "search_field")) self.send_text(text, *self.locator(self.nmf_locators, "search_field")) self.page_has_loaded() @allure.step("NMF - Filter clear icon is present") def nmf_filter_clear_icon_is_present(self): self.wait_for_element_visible(*self.locator(self.nmf_locators, "clear_icon")) is_present = self.is_element_present(*self.locator(self.nmf_locators, "clear_icon")) assert_that(is_present).is_true() @allure.step("NMF search - move focus out of the field") def focus_out_of_the_search_field(self): sort_by_dd_sel = "//*[text()='Sort By']/following-sibling::*/*" sort_by_dd = self.wait_for_element_visible(sort_by_dd_sel, "xpath") self.click_element(element=sort_by_dd) @allure.step("NMF - click export") def nmf_click_export(self): self.scroll_to_element(*self.locator(self.nmf_locators, "export")) export = self.wait_for_element_clickable(*self.locator(self.nmf_locators, "export")) self.click_on_element_js(element=export) self.wait_for_element_clickable(*self.locator(self.nmf_locators, "export")) @allure.step("NMF - get track indicators parameter for index") def get_track_indicators(self, index=0): parameters_sel = f"//*[contains(@id, 'new-music-friday-table-row-{index}-track') and contains(@id, 'params')]/*/*" parameters_el = self.get_elements(parameters_sel, "xpath") parameters = [self.get_text(element=p) for p in parameters_el] assert_that(["Featuring", "Top 10 Rank", "Avg. Position"]).is_equal_to(parameters[:3]) parameters = [int(p) for p in parameters[3:]] self.log.info(f"parameters nmf: {parameters}") return parameters @allure.step("NMF - set nmf date using url") def set_nmf_date_using_url(self, date): current_date = self.track_page.parameter_from_url(self.nmf_date) self.track_page.replace_param_in_url(self.nmf_date, current_date, date) date_dd_value = self.get_text(locator=self.date_dd_locator, locator_type="xpath") selected_date = datetime.datetime.strptime(date_dd_value, self.track_page.get_date_format_from_locale()).strftime("%Y-%m-%d") assert_that(date).is_equal_to(selected_date) @allure.step("NMF - get track names per loaded page") def get_nmf_track_names_per_page_loaded(self): track_names_locator = "//*[contains(@href, '/spotify/track/')][string-length(.) > 0]" self.wait_for_element_visible(locator=track_names_locator, locator_type="xpath") 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("NMF - get track artists per loaded page") def get_nmf_track_artists_per_page_loaded(self): artists_locator = "//*[contains(@id, 'artist-link')]" self.wait_for_element_visible(locator=artists_locator, locator_type="xpath") artists_els = self.get_elements(locator=artists_locator, locator_type="xpath") artists_list = [self.get_text(element=e) for e in artists_els] self.log.info("Artists list: " + str(artists_list)) return artists_list @allure.step("NMF - get sony tracks amount per loaded page") def get_sony_tracks_amount_per_page_loaded(self): label_locator = "//*[contains(@id, 'label')]" labels_amount = len(self.get_elements(locator=label_locator, locator_type="xpath")) self.log.info("Sony tracks amount: " + str(labels_amount)) return labels_amount @allure.step("NMF - open track page") def open_track_page_from_nmf(self, track_name): track_name_locator = f"//*[contains(text(), '{track_name}')]" track_name = self.get_element(locator=track_name_locator, locator_type="xpath") self.click_element(element=track_name) @allure.step("NMF - is track has sony label") def is_track_has_sony_label(self, track_id): label_locator = f"new-music-friday-table-row-0-track-{track_id}-label" label = self.is_element_present(locator=label_locator, locator_type="xpath") self.log.info("Label: " + str(label)) return label @allure.step("NMF - Check for filtered values in the table") def nmf_table_is_filtered_by(self, value): track_names_list = self.get_nmf_track_names_per_page_loaded() table_artists_list = self.get_nmf_track_artists_per_page_loaded() tracks_list = list(zip(track_names_list, table_artists_list)) 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("NMF - verify No results message after filtering") def verify_nmf_no_results_message(self): no_results_to_show = self.wait_for_element_visible(*self.locator(self.nmf_locators, "table_no_results_to_show")) try_changing = self.wait_for_element_visible(*self.locator(self.nmf_locators, "try_to_change")) no_results_to_show_text = self.get_text(element=no_results_to_show) try_changing_text = self.get_text(element=try_changing) assert_that(no_results_to_show_text).is_equal_to("No results to show.") assert_that(try_changing_text).is_equal_to("Try changing filtering parameters.") @allure.step("NMF - get date from UI") def get_chosen_nmf_date(self): date_dd_locator = "//*[contains(@class, 'icon')]/preceding-sibling::*[contains(text(), '/')]" date_dd = self.wait_for_element_visible(date_dd_locator, "xpath") return self.get_text(element=date_dd)