import logging import time from datetime import datetime, timedelta import allure from assertpy import assert_that from dateutil import rrule from natsort import natsorted from selenium.common.exceptions import NoSuchElementException 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.artist_page import ArtistPage from app.src.pages.login_page import LoginPage from app.src.pages.track_page import TrackPage class TopChartsPage(BasePage): log = cl.Logger(logging.DEBUG) NOT_ACTIVE_FILTER_COLOR = "rgba(0, 0, 0, 1)" ACTIVE_EMPTY_FILTER_COLOR = "rgba(255, 255, 255, 1)" ACTIVE_FILTER_COLOR = ["rgba(0, 0, 0, 1)", "rgba(255, 255, 255, 1)"] HOVERED_FILTER_COLOR = "0, 0, 0" SPOTIFY_TYPE = "spotify" APPLE_TYPE = "apple" YOUTUBE_TYPE = "youtube" TRENDING_TYPE = "trending" SHAZAM_TYPE = "shazam" AMAZON_TYPE = "amazon" ENTRY = "Entry" DOWN = "Down" DOWN_MORE_5 = "Down_5" UP = "Up" UP_MORE_5 = "Up_5" ZERO = "Zero" DAILY = "daily" WEEKLY = "weekly" trending_date = "trending_date" PERIOD_DD_HINT_SPOTIFY = """Streams numbers seen below for Spotify are pulled directly from SpotifyCharts.com and could be different from the streams numbers seen on the track pages on Apollo""" tab = "tab" market = "market" date = "date" city = "city" chart_type = "chart_type" TRENDING_DATEPICKER_TODAY_MAX_DATE_COLOR = "rgba(255, 60, 129, 1)" TRENDING_DATEPICKER_MAX_DATE_COLOR = "rgba(14, 16, 26, 1)" TRENDING_DETAILS_POPUP_GRAPH_POSITION_LINE_COLOR = "rgba(106, 110, 148, 1)" def __init__(self, driver): super().__init__(driver) self.driver = driver self.top_charts_locators = self.get_page_locators("TopChartsPage", "top_charts_elements.json") self.loginPage = LoginPage(self.driver) self.trackPage = TrackPage(self.driver) self.artist_page = ArtistPage(self.driver) self.api_client = ApiClient() self.sql_client = MySqlClient() self.ts = TestStatus(self.driver) @allure.step("opening Top Charts page") def open_top_chart_page(self): self.driver.get(CoreConfig.ENV_BASE_URL + "/top-charts") self.top_chart_page_is_opened() @allure.step("Top Charts page is opened") def top_chart_page_is_opened(self): self.wait_for_chart_table() self.wait_for_table_load() self.page_has_loaded() time.sleep(5) title_el = self.wait_for_element_visible(*self.locator(self.top_charts_locators, "charts-title")) is_title_displayed = self.is_element_displayed(element=title_el) self.ts.markFinal(is_title_displayed, "Top Charts page is opened") @allure.step("Switching DSP tab") def switch_tab(self, dsp): self.wait_for_table_load() tab = self.wait_for_element_clickable(*self.locator(self.top_charts_locators, f"{dsp}-tab")) self.click_element(element=tab) self.page_has_loaded() @allure.step("Getting clock tooltip value") def get_clock_tooplip(self): clock_element = self.get_element(*self.locator(self.top_charts_locators, "apple-clock-icon")) ActionChains(self.driver).move_to_element(clock_element).perform() time.sleep(1) tool = self.wait_for_element_visible(*self.locator(self.top_charts_locators, "apple-hint-icon-tooltip")) text = self.get_text(element=tool) return text @allure.step("Trying to find clock icon") def clock_element_is_present(self): return self.is_element_present(*self.locator(self.top_charts_locators, "apple-clock-icon")) @allure.step("Trying to find Spotify Filter element") def filter_is_present(self, dsp): selector_value = "{dps_prefix}-filter".format(dps_prefix=dsp) is_present = self.is_element_present(*self.locator(self.top_charts_locators, selector_value)) self.ts.markFinal(is_present, "Filter element exists for {}".format(dsp)) @allure.step("Verify default filter input") def verify_default_filter(self, dsp, search_icon_type): selector_value = f"{dsp}-filter" input_field = self.wait_for_element_visible(*self.locator(self.top_charts_locators, selector_value)) icon_locator = f"top-charts-{search_icon_type}-filter-input-search-icon" icon = self.wait_for_element_visible(locator=icon_locator) 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("background-color") self.wait_for_element_clickable(*self.locator(self.top_charts_locators, selector_value)) self.click_element(element=input_field) color_after = input_field.value_of_css_property("background-color") 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("Filter is in focus") def verify_filter_is_in_focus(self, dsp, active=True): selector_value = f"{dsp}-filter" input_field = self.wait_for_element_visible(*self.locator(self.top_charts_locators, selector_value)) if active: self.click_element(element=input_field) focused_el = self.driver.switch_to.active_element assert_that(input_field).is_equal_to(focused_el) else: focused_el = self.driver.switch_to.active_element assert_that(input_field).is_not_equal_to(focused_el) @allure.step("Checking for Spotify or Apple Filter placeholder value") def filter_placeholder_should_present(self, should_have_placeholder_value, dsp): selector_value = "{dps_prefix}-filter".format(dps_prefix=dsp) if should_have_placeholder_value: placeholder = self.get_attribute_value(*self.locator(self.top_charts_locators, selector_value), None, "placeholder") self.ts.markFinal(placeholder == "Filter", "Filter have placeholder") value = self.get_attribute_value(*self.locator(self.top_charts_locators, selector_value), None, "value") self.ts.markFinal(value == "", "Current value is empty") else: value = self.get_attribute_value(*self.locator(self.top_charts_locators, selector_value), None, "value") assert_that(value).is_not_empty() @allure.step("Changing Spotify Filter value") def change_filter_value(self, value, dsp): selector_value = f"{dsp}-filter" self.wait_for_element_clickable(*self.locator(self.top_charts_locators, selector_value)) self.clear_text(*self.locator(self.top_charts_locators, selector_value)) self.send_text(value, *self.locator(self.top_charts_locators, selector_value)) time.sleep(3) @allure.step("Check for filtered values in the table") def table_is_filtered_by(self, value): self.wait_for_element_visible(*self.locator(self.top_charts_locators, "charts-table-track-rows")) table_track_name_with_artist = self.get_elements(*self.locator(self.top_charts_locators, "charts-table-track-rows")) table_track_name_with_artist_texts = [self.get_text(element=t) for t in table_track_name_with_artist] self.log.info("Table names: " + str(table_track_name_with_artist_texts)) for t in table_track_name_with_artist_texts[:11]: assert_that(t.lower()).contains(value.lower()) @allure.step("Filter clear icon is present") def clear_filter_icon_is_present(self): self.wait_for_element_visible(*self.locator(self.top_charts_locators, "spotify-filter-clear-icon")) is_present = self.is_element_present(*self.locator(self.top_charts_locators, "spotify-filter-clear-icon")) assert_that(is_present).is_true() @allure.step("Clearing Spotify filter by clear icon") def spotify_filter_click_clear_icon(self): self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "spotify-filter-clear-icon")) self.click_element(*self.locator(self.top_charts_locators, "spotify-filter-clear-icon")) time.sleep(3) @allure.step("Get first track name") def get_first_track_name(self): first_track_row = self.get_elements(*self.locator(self.top_charts_locators, "charts-table-first-track-name"))[0] track_name = self.get_text(element=first_track_row) self.log.info("name: " + track_name) return str(track_name) @allure.step("Verify table is empty") def table_is_empty(self): is_present = self.wait_for_element_visible(*self.locator(self.top_charts_locators, "empty-table"), timeout=5) return is_present @allure.step("Table still in loading progress") def wait_for_table_load(self): self.wait_for_element_visible(locator="//div[@class='ReactVirtualized__Grid__innerScrollContainer']", locator_type="xpath", timeout=10) @allure.step("Changing Spotify sub-tab") def change_sub_tab(self, tab): if tab == self.WEEKLY: self.click_element(*self.locator(self.top_charts_locators, "{}-tab".format(self.WEEKLY))) self.page_has_loaded() self.verify_chosen_switch(self.WEEKLY) else: self.click_element(*self.locator(self.top_charts_locators, "{}-tab".format(self.DAILY))) self.page_has_loaded() self.verify_chosen_switch(self.DAILY) self.page_has_loaded() @allure.step("Change Spotify sub market filter") def change_spotify_market(self, market): self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "charts-owner-market-filter-dd")) self.click_element(*self.locator(self.top_charts_locators, "charts-owner-market-filter-dd")) source = f"//*[contains(@id,'spotify-market-dd')]//../*[text()='{market}']" # source_market = self.get_element(locator=source, locator_type="xpath") # self.scroll_to_element(locator=source, locator_type="xpath") self.click_on_element_js(element=self.get_element(source, "xpath")) @allure.step("Change Apple market") def change_apple_market(self, market): self.wait_for_element_visible(*self.locator(self.top_charts_locators, "charts-owner-market-dd")) self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "charts-owner-market-dd")) self.click_element(*self.locator(self.top_charts_locators, "charts-owner-market-dd")) source = "//*[@id='top-charts-apple-market-dd']//..//*[text()='{}']".format(market) self.click_on_element_js(self.get_element(locator=source, locator_type="xpath")) self.verify_apple_market(market=market) @allure.step("Verify Apple market") def verify_apple_market(self, market): e = self.wait_for_element_visible(*self.locator(self.top_charts_locators, "charts-owner-market-dd")) self.ts.markFinal(self.get_text(element=e) == market, "owner market is: {}".format(self.get_text(element=e))) @allure.step("Click Spotify sub filter Apply") def click_spotify_apply(self): self.click_element(*self.locator(self.top_charts_locators, "spotify-sub-filter-apply")) self.page_has_loaded() @allure.step("Check filter menu button have proper styles") def filter_is_enabled(self, should_be_active, dsp, should_be_empty=True): self.wait_for_element_visible(*self.locator(self.top_charts_locators, "{}-sub-filter-menu".format(dsp)), timeout=5) time.sleep(5) filter_button_span = self.get_element(*self.locator(self.top_charts_locators, "{}-sub-filter-menu-icon".format(dsp))) color = filter_button_span.value_of_css_property("color") if should_be_active: if should_be_empty: self.ts.markFinal( color == self.ACTIVE_EMPTY_FILTER_COLOR, "Active Empty filter have proper style. Should be :" + color, ) else: self.ts.markFinal(color in self.ACTIVE_FILTER_COLOR, "Active filter have proper style. Should be :" + color) else: self.ts.markFinal(color == self.NOT_ACTIVE_FILTER_COLOR, "Not active filter have default style. Should be :" + color) @allure.step("Check hover style changes of filter button menu") def verify_filter_hover_state(self, menu="apple"): time.sleep(2) button_background = self.get_element(*self.locator(self.top_charts_locators, "{}-sub-filter-menu-background".format(menu))) color_before_hover = button_background.value_of_css_property("background-color") ActionChains(self.driver).move_to_element(self.get_element(*self.locator(self.top_charts_locators, "{}-sub-filter-menu".format(menu)))).perform() color_after_hover = button_background.value_of_css_property("background-color") self.ts.markFinal(color_before_hover != color_after_hover, "Hovering changing color of the filter button") @allure.step("Open Filter menu") def open_filter_menu(self, dsp): self.wait_for_table_load() self.wait_for_chart_table() selector = "{dsp}-sub-filter-menu".format(dsp=dsp) self.wait_for_element_visible(*self.locator(self.top_charts_locators, selector)) menu = self.wait_for_element_clickable(*self.locator(self.top_charts_locators, selector)) self.click_element(element=menu) @allure.step("Check for all available options") def verify_apple_filter_available_options(self): if ( not self.is_element_displayed(locator='//span[text()="Track Owner"]', locator_type="xpath") or not self.is_element_displayed(locator='//span[text()="Sony Tracks"]', locator_type="xpath") or not self.is_element_displayed(locator='//span[text()="Non-Sony Tracks"]', locator_type="xpath") or not self.trackPage.is_checked(*self.locator(self.top_charts_locators, "charts-apple-filter-dd-checkbox-sony")) or not self.trackPage.is_checked(*self.locator(self.top_charts_locators, "charts-apple-filter-dd-checkbox-non-sony")) or self.is_enabled(*self.locator(self.top_charts_locators, "charts-apple-filter-dd-apply-btn")) ): self.ts.markFinal(False, "Some Apple filter elements are missing or not in default disabled state") else: self.ts.markFinal(True, "Apple filter are in default state") @allure.step("Clicking on any header element, so filter popup will be closed") def click_on_header(self): chart_title = self.get_element(*self.locator(self.top_charts_locators, "charts-title")) ActionChains(self.driver).move_to_element(chart_title).perform() self.click_on_element_js(chart_title) time.sleep(1) @allure.step("Activating filtering option") def filter_menu_check_option(self, option): self.open_filter_menu(self.APPLE_TYPE) # checking for option self.click_element(*self.locator(self.top_charts_locators, "charts-apple-filter-dd-checkbox-{option}".format(option=option))) @allure.step("Check for applied styles of filter buttons") def filter_buttons_activated(self, should_be_active): if self.is_enabled(*self.locator(self.top_charts_locators, "charts-apple-filter-dd-apply-btn")): self.ts.markFinal(should_be_active, "Apple and Reset buttons are enabled") @allure.step("Press on filter Apply button") def filter_apply(self, activate_filter): if activate_filter: self.click_element(*self.locator(self.top_charts_locators, "charts-apple-filter-dd-apply-btn")) time.sleep(2) @allure.step("Check for activated filter values") def filter_is_selected(self, checkbox, market): return self.trackPage.is_checked(*self.locator(self.top_charts_locators, "charts-apple-filter-dd-checkbox-{0}".format(checkbox))) @allure.step("Changing Spotify Chart date - from calendar") def open_spotify_chart_for_date(self, date): current_date = self.get_chosen_date() self.log.info("current date: {}, change to date: {}".format(current_date, date)) if date != current_date: self.wait_for_table_load() dd = self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "charts-period-dd")) ActionChains(self.driver).move_to_element(to_element=dd).click(on_element=dd).send_keys(Keys.BACK_SPACE).send_keys(date).send_keys(Keys.ENTER).perform() self.wait_for_table_load() @allure.step("Changing Spotify Chart date - dropdown") def open_spotify_chart_for_date_dd(self, date): current_date = self.get_chosen_date() self.log.info("current date: {}, change to date: {}".format(current_date, date)) if date != current_date: self.wait_for_table_load() dd = self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "charts-period-dd")) self.click_element(element=dd) selected_date_element = self.get_element(locator='//div[text()="{}"]'.format(date), locator_type="xpath") self.click_on_element_js(element=selected_date_element) self.wait_for_table_load() @allure.step("Get chosen date on ui") def get_chosen_date(self): self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "charts-period-dd")) date_dd = self.wait_for_element_visible(*self.locator(self.top_charts_locators, "charts-period-dd")) current_date = self.get_text(element=date_dd) if current_date in [None, ""]: current_date = self.get_attribute_value(element=date_dd, attribute="value") self.log.info(f"current_date: {current_date}") return current_date @allure.step("Find track in Chart") def check_track_for_position(self, trackId, position, trend, trend_value=0): have_position = True have_trend = True have_trend_position = True self.wait_for_element_visible(*self.locator(self.top_charts_locators, "charts-table-track-position")) table_track_position = self.get_elements(*self.locator(self.top_charts_locators, "charts-table-track-position")) have_position = self.find_value_in_row(position, *table_track_position) self.ts.markFinal(have_position, 'Track position is "{0}"'.format(str(position))) have_trend = self.find_trend_arrow_in_row(trend) if trend != self.ENTRY: table_track_trend = self.get_elements(*self.locator(self.top_charts_locators, "charts-table-track-trend")) have_trend_position = self.find_value_in_row(trend_value, *table_track_trend) self.ts.markFinal(have_trend_position, 'Track trend is "{0}"'.format(str(trend_value))) return have_position and have_trend and have_trend_position @allure.step("Find trend position") def find_value_in_row(self, value, *table_row): have_trend_position = False for row in table_row: text = str(self.get_text(element=row)) self.log.info("test is " + text) self.log.info("trend value is " + str(value)) if str(value).lower() in text.lower(): have_trend_position = True break return have_trend_position @allure.step("Find trend arrow in a row") def find_trend_arrow_in_row(self, trend): table_track_trend = self.get_elements(*self.locator(self.top_charts_locators, "charts-table-track-trend")) have_trend = False class_path = "icon-arrow-right" # zero class if trend == self.UP: class_path = "icon-arrow-diag-top" if trend == self.UP_MORE_5: class_path = "icon-arrow-up" if trend == self.DOWN: class_path = "icon-arrow-diag-bottom" if trend == self.DOWN_MORE_5: class_path = "icon-arrow-down" if trend == self.ENTRY: class_path = "icon-chart-circle" for row in table_track_trend: try: element_exist = self.is_element_displayed(f"//*[contains(@class, '{class_path}')]", "xpath") if element_exist: have_trend = True break except NoSuchElementException: pass assert_that(have_trend).described_as(trend).is_true() return have_trend @allure.step("Exporting file") def export_file(self, market, token, append_name=""): spotify = "Spotify" dsp = spotify daily_weekly = self.DAILY if self.get_attribute_value(*self.locator(self.top_charts_locators, "{}-tab".format(self.APPLE_TYPE)), attribute="data-selected") == "selected": dsp = "Apple Music" date = self.api_client.get_vendor_api_tracks(vendor=self.APPLE_TYPE, market=market["db"], end=100, token=token)["chart_date"] date = datetime.strptime(date, "%Y-%m-%d").strftime(self.trackPage.get_date_file_format_from_locale()) session_id = self.driver.session_id if market == AppConfig.get("market")["global"]: file_path = "http://{host}:4444/download/{session_id}/{date} - {country} - Apple Music Top 100.csv".format( host=CoreConfig.SELENOID_HOST, session_id=session_id, country=market["name"], date=date, ) else: file_path = "http://{host}:4444/download/{session_id}/{date} - {country} - Apple Music Top 100.csv".format( host=CoreConfig.SELENOID_HOST, session_id=session_id, country=str(market["market"]).upper(), date=date, ) elif dsp == spotify: if self.get_attribute_value(*self.locator(self.top_charts_locators, "{}-tab".format(self.WEEKLY)), attribute="data-selected") == "selected": daily_weekly = self.WEEKLY date = self.get_chosen_date() date = datetime.strptime(date, self.trackPage.get_date_format_from_locale()).strftime(self.trackPage.get_date_file_format_from_locale()) session_id = self.driver.session_id file_path = "http://{host}:4444/download/{session_id}/{date}_{dsp}_{country}_top {daily_weekly} chart{append_name}.csv".format( host=CoreConfig.SELENOID_HOST, session_id=session_id, dsp=dsp, daily_weekly=daily_weekly, country=market["name"], date=date, append_name=append_name, ) self.scroll_to_element(*self.locator(self.top_charts_locators, "charts-title")) self.wait_for_element_visible("charts-table-cell-name-1") export_button = self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "export_button")) self.click_element(element=export_button) self.log.info("file: {}".format(file_path)) columns = ["Track Position", "Position Trend", "Track Name", "Artist", "Is Sony?"] if dsp == spotify: columns.append("Streams data") time.sleep(5) data = self.trackPage.read_from_csv(file_path) self.log.info("data: {}".format(data)) file = {} for c in columns: file[c] = data.get(c) self.log.info("file: {}".format(file)) return file @allure.step("Wait for chart table visible") def wait_for_chart_table(self): self.page_has_loaded() self.wait_for_element_visible(*self.locator(self.top_charts_locators, "charts-table")) self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "charts-table")) @allure.step("Search for TrackId in file") def track_is_in_file(self, file, trackId): # try to find given trackID by data in the file, which were returned by export_file method return True @allure.step("Find track entries for date") def find_in_entries(self, trackID, vendor, market, date): user = self.loginPage.get_user_email_with_worker() token = self.api_client.authorize(user=user) response = self.api_client.get_charts_additions(vendor, market, date, token) for item in response["tracks"]: if item["id"] == trackID: return True return False @allure.step("Find track exists for date") def find_in_exists(self, trackID, vendor, market, date): user = self.loginPage.get_user_email_with_worker() token = self.api_client.authorize(user=user) response = self.api_client.get_charts_removals(vendor, market, date, token) for item in response["tracks"]: if item["id"] == trackID: return True return False @allure.step("Selecting market") def select_market(self, market): self.wait_for_element_visible(*self.locator(self.top_charts_locators, "market_picker")) self.click_element(*self.locator(self.top_charts_locators, "market_picker")) market_item = "//*[contains(@id, 'header-market-switcher-item-')][contains(@id, '-label')][text()='{}']".format(market) market_item = self.get_element(market_item, "xpath") self.click_on_element_js(market_item) @allure.step("Get Track at specific position") def get_track_at_position(self, position): max_iterations = 100 current_iteration = 0 position_locator = "//div[contains(@id,'charts-table-cell-position-{}')]" found_position = 0 track_row = None while found_position < position: if current_iteration > max_iterations: break current_iteration = current_iteration + 1 tracks = self.get_elements(position_locator.format(""), "xpath") for track in tracks: found_position = int(self.get_text(element=track)) if found_position == position: track_row = track break if not track_row: self.log.info("scrolling to +" + position_locator.format(str(found_position))) self.scroll_to_element(position_locator.format(str(found_position)), "xpath") if not track_row: return None result = dict() result["position"] = int(self.get_text(locator="//div[contains(@id, 'charts-table-cell-position-{}')]".format(position), locator_type="xpath")) result["link"] = str( self.get_attribute_value( locator="//div[contains(@id, 'charts-table-cell-name-{}')]//a".format(position), locator_type="xpath", attribute="href", ) ) result["image"] = str( self.get_attribute_value( locator="//div[contains(@id, 'charts-table-cell-image-{}')]//img".format(position), locator_type="xpath", attribute="src", ) ) result["streams"] = str(self.get_text(locator="//div[contains(@id, 'charts-table-cell-streams-{}')]".format(position), locator_type="xpath")) result["trendValue"] = str(self.get_text(locator="//div[contains(@id, 'charts-table-cell-trend-{}')]".format(position), locator_type="xpath")) result["trendType"] = self.get_trend_type("//div[contains(@id, 'charts-table-cell-trend-{}')]".format(position)) result["name"] = str(self.get_text(locator="//div[contains(@id, 'charts-table-cell-name-{}')]".format(position), locator_type="xpath")) self.log.info("Created track object :") self.log.info(result) return result @allure.step("Getting trend type from class name") def get_trend_type(self, locator): class_name = self.get_element(locator=locator + "/*/*/*/*/span", locator_type="xpath").get_attribute("class") last_class_name = class_name.split()[-1] self.log.info("found trend class name :" + last_class_name) if last_class_name == "icon-arrow-diag-top": return self.UP if last_class_name == "icon-arrow-up": return self.UP_MORE_5 if last_class_name == "icon-arrow-diag-bottom": return self.DOWN if last_class_name == "icon-arrow-down": return self.DOWN_MORE_5 if last_class_name == "icon-chart-circle": return self.ENTRY if last_class_name == "icon-arrow-right": return self.ZERO @allure.step("Top CHarts page - verify spotify filter options") def vetify_spotify_filter_available_options(self, open=True): if open: elements_locs = [ "track_owner_header", "sony_title", "non_sony_title", "spotify-sub-filter-apply", "check_box_sony", "check_box_non_sony", ] for loc in elements_locs[:-2]: assert_that(self.is_element_displayed(*self.locator(self.top_charts_locators, loc))).described_as(loc).is_true() for loc in elements_locs[-2:]: assert_that(self.is_element_present(*self.locator(self.top_charts_locators, loc))).described_as(loc).is_true() else: is_open = self.is_element_displayed(*self.locator(self.top_charts_locators, "track_owner_header")) self.ts.markFinal(not is_open, "filter window for spotify is open") @allure.step("Top Charts page - verify owner market") def verify_owner_market(self, param): owner_market = self.get_text(*self.locator(self.top_charts_locators, "charts-owner-market-filter-dd")) self.ts.markFinal(owner_market == param, "owner market is: {}".format(owner_market)) @allure.step("Top CHarts - filter table check sony tracks") def filter_check_sony_tracks(self, checked=True, apply_filter=True): if self.trackPage.is_checked(*self.locator(self.top_charts_locators, "check_box_non_sony")): self.click_element(*self.locator(self.top_charts_locators, "check_box_non_sony")) if not self.trackPage.is_checked(*self.locator(self.top_charts_locators, "check_box_sony")): self.click_element(*self.locator(self.top_charts_locators, "check_box_sony")) apply = self.is_enabled(*self.locator(self.top_charts_locators, "spotify-sub-filter-apply")) if apply_filter: self.click_element(*self.locator(self.top_charts_locators, "spotify-sub-filter-apply")) self.ts.markFinal(apply == checked, "apply is enabled") @allure.step("Top Charts - get track names") def get_track_names(self): self.page_has_loaded() self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "export_button")) self.wait_for_element_visible(*self.locator(self.top_charts_locators, "charts-table-first-track-name")) tracks = self.get_elements(*self.locator(self.top_charts_locators, "charts-table-first-track-name")) names = [self.get_text(element=e) for e in tracks] self.log.info("names: {}".format(names)) return names @allure.step("Top Charts - get trending video names") def get_trending_video_names(self, tab=TRENDING_TYPE, scroll=True): self.page_has_loaded() if scroll: self.scroll_to_last_position() self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "export_button")) self.wait_for_element_visible(*self.locator(self.top_charts_locators, f"charts-{tab}-video-name")) videos = self.get_elements(*self.locator(self.top_charts_locators, f"charts-{tab}-video-name")) names = [self.get_text(element=e) for e in videos] self.log.info("Video names: {}".format(names)) return names @allure.step("Top CHarts - verify selected filters") def verify_enabled_filters(self, sony=False, non_sony=False): filter_checkbox_non_sony = self.trackPage.is_checked(*self.locator(self.top_charts_locators, "check_box_non_sony")) filter_checkbox_sony = self.trackPage.is_checked(*self.locator(self.top_charts_locators, "check_box_sony")) assert_that(filter_checkbox_sony).is_equal_to(sony) assert_that(filter_checkbox_non_sony).is_equal_to(non_sony) @allure.step("Top Charts - filter non sony tracks") def filter_check_non_sony_tracks(self, checked=True, apply_filter=True): if not self.trackPage.is_checked(*self.locator(self.top_charts_locators, "check_box_non_sony")): self.click_element(*self.locator(self.top_charts_locators, "check_box_non_sony")) if self.trackPage.is_checked(*self.locator(self.top_charts_locators, "check_box_sony")): self.click_element(*self.locator(self.top_charts_locators, "check_box_sony")) apply = self.is_enabled(*self.locator(self.top_charts_locators, "spotify-sub-filter-apply")) if apply_filter: self.click_element(*self.locator(self.top_charts_locators, "spotify-sub-filter-apply")) self.ts.markFinal(apply == checked, "apply is enabled") @allure.step("Top Charts - get position trends for table") def get_position_trends_for_index(self, index): trends_el = self.get_text("charts-table-cell-trend-{}".format(index)) trends = str(trends_el).strip() self.log.info("index: {}, trends: {}".format(index, trends)) return trends @allure.step("Top Charts - get track_name for table") def get_track_names_for_index(self, index): trends_el = self.get_text("charts-table-cell-name-{}".format(index)) self.log.info("index: {}, track names : {}".format(index, trends_el)) return trends_el @allure.step("Top Charts - get track_streams for table") def get_track_streams_for_index(self, index): trends_el = self.get_text("charts-table-cell-streams-{}".format(index)) trends = int(str(trends_el).replace(",", "").replace("None", "0")) self.log.info("track streams: {}".format(trends)) return trends @allure.step("Top Charts - get last position") def get_last_position(self): self.driver.execute_script("window.scrollBy(0,document.body.scrollHeight)", "") last_position = self.get_elements(locator="//*[contains(@id, 'charts-table-cell-position-')]", locator_type="xpath")[-1] self.log.info("Last position: " + str(int(self.get_text(element=last_position)))) return int(self.get_text(element=last_position)) @allure.step("Top Charts - get last position") def scroll_to_last_position(self): position = self.get_last_position() self.scroll_to_element(locator="charts-table-cell-position-{}".format(position), locator_type="id") @allure.step("Top Charts - get all from table") def get_all_from_table(self, count=200): first_position = 1 last_position = self.get_last_position() names = [] trends = [] streams = [] positions = [] while last_position <= count: for r in list(range(first_position, last_position + 1)): names.append(self.get_track_names_for_index(r)) trends.append(self.get_position_trends_for_index(r)) streams.append(self.get_track_streams_for_index(r)) positions.append(self.get_track_positions_for_index(r)) self.log.info("names: {}, \ntrends: {}, \nstreams: {}".format(names, trends, streams)) if last_position == count: break self.scroll_to_last_position() first_position = last_position + 1 last_position = self.get_last_position() self.page_has_loaded() if count == (100 or 200): self.ts.markFinal(len(names) == count, f"count names: {len(names)}\nexpected: {count}") self.ts.markFinal(len(streams) == count, "count streams: {}".format(len(streams))) self.ts.markFinal(len(trends) == count, "count trends: {}".format(len(trends))) ui = [ zip(positions, trends, names, streams), {"positions": positions, "trends": trends, "names": names, "streams": streams}, ] self.log.info("from table: {}".format(ui[1])) return ui @allure.step("Top Charts - get track positions for table") def get_track_positions_for_index(self, index): trends_el = self.get_text("charts-table-cell-position-{}".format(index)) trends = int(str(trends_el).replace(",", "")) self.log.info("track position: {}".format(trends)) return trends @allure.step("Top Charts - verify blue dot hover") def verify_blue_dot_hover(self, ui_table_tr, track, new_reentry, tab="spotify", present=True): index = 0 ui_data_tracks = [str(r).split("\n")[0] for r in ui_table_tr] self.log.info("ui_data: {}, \n track: {}".format(ui_data_tracks, track)) for r in ui_data_tracks: if r == track: index = ui_data_tracks.index(r) + 1 self.log.info("index for blue dot is: {}".format(index)) if index > 4: index_to_scroll = index - 4 else: index_to_scroll = index self.scroll_to_track_with_index(index_to_scroll, tab=tab) self.scroll_to_element(locator="charts-table-cell-trend-{}".format(index_to_scroll), locator_type="id") dot = self.get_element(locator="charts-table-cell-trend-{}".format(index)) ActionChains(self.driver).move_to_element(to_element=dot).perform() if new_reentry == "new": hint = self.is_element_displayed(locator="//*[text()='New Entry']", locator_type="xpath") elif new_reentry == "reentry": hint = self.is_element_displayed(locator="//*[text()='Re-Entry']", locator_type="xpath") self.log.info("Hint: " + str(hint)) assert_that(hint).is_equal_to(present) @allure.step("Top Charts - scroll to track with index") def scroll_to_track_with_index(self, index, tab="spotify"): self.scroll_to_element(*self.locator(self.top_charts_locators, "charts-title")) self.click_element(*self.locator(self.top_charts_locators, "charts-title")) if tab == "spotify": self.get_all_from_table(count=index) else: self.get_all_from_table_apple(count=index) @allure.step("Top Charts - change week") def change_week(self, date): self.scroll_to_element(*self.locator(self.top_charts_locators, "charts-title")) @allure.step("Top Charts - verify chosen switch") def verify_chosen_switch(self, tab): selected = self.get_attribute_value(*self.locator(self.top_charts_locators, "{}-tab".format(tab)), attribute="data-selected") == "selected" self.ts.markFinal(selected, "tab: {} is selected".format(tab)) @allure.step("Top Charts - verify period dd hint") def verify_period_dd_info_icon(self): icon = self.get_element(*self.locator(self.top_charts_locators, "charts-spotify-hint-icon")) ActionChains(self.driver).move_to_element(to_element=icon).perform() tool = self.get_text(*self.locator(self.top_charts_locators, "charts-spotify-hint-icon-tooltip")).replace("\n", " ") assert_that(tool).is_equal_to(self.PERIOD_DD_HINT_SPOTIFY) @allure.step("Top Charts - verify elements") def verify_elements(self, dsp): self.page_has_loaded() charts_title = self.get_element(*self.locator(self.top_charts_locators, "charts-title")) charts_title_text = self.get_text(element=charts_title) assert_that(charts_title_text).is_equal_to("Charts") charts_tabs = [] for tab in [self.SPOTIFY_TYPE, self.APPLE_TYPE, self.YOUTUBE_TYPE, self.SHAZAM_TYPE, self.AMAZON_TYPE]: tab_el = self.get_element(*self.locator(self.top_charts_locators, f"{tab}-tab")) tab_text = self.get_text(element=tab_el) charts_tabs.append(tab_text) if tab == dsp: icon_loc = "(//span[contains(@class, 'icon-{}')])[2]" else: icon_loc = "//span[contains(@class, 'icon-{}')]" icon_el = self.is_element_displayed(locator=icon_loc.format(tab), locator_type="xpath") assert_that(icon_el).is_true() assert_that(charts_tabs).is_equal_to(["TOP 200", "TOP 100", "TRENDING MUSIC VIDEOS", "TOP 200", "TOP TRACKS"]) info_icon = self.get_element(f"top-charts-{dsp}-hint-icon") datepicker_el = self.is_element_displayed(f"top-charts-{dsp}-period-dd") clock_icon = self.is_element_displayed(f"top-charts-{dsp}-day-picker-hint-icon") owner_market_filter = self.is_element_displayed(f"top-charts-{dsp}-market-dd") filter_el = self.is_element_displayed(f"top-charts-{dsp}-filter-input") filter_icon = self.is_element_displayed(f"top-charts-{dsp}-filter-input-search-icon") export = self.is_element_displayed(f"top-charts-{dsp}-export-btn") els = [info_icon, datepicker_el, clock_icon, owner_market_filter, filter_el, filter_icon, export] assert_that(set(els)).is_true() @allure.step("Top Charts - compare ui and db") def compare_ui_with_api_spotify(self, table_ui, table_api): tracks_ui = [str(t).replace("SONY", "").split("\n")[0] for t in table_ui["names"]] self.log.info("UI tracks: " + str(tracks_ui)) artists_ui = [str(t).replace("SONY\n", "").split("\n")[1] for t in table_ui["names"]] self.log.info("UI artists: " + str(artists_ui)) trends_ui = [] for t in table_ui["trends"]: if str(t) != "": trends_ui.append(int(t)) self.log.info("UI trends: " + str(trends_ui)) positions_api = [table_api["tracks"][p]["position"] for p in range(len(table_api["tracks"]))] streams_api = [table_api["tracks"][s]["streams"] for s in range(len(table_api["tracks"]))] names_api = [table_api["tracks"][t]["name"] for t in range(len(table_api["tracks"]))] artists_api = [table_api["tracks"][a]["artist"] for a in range(len(table_api["tracks"]))] trends_api = [abs(table_api["tracks"][tr]["trend"]) for tr in range(len(table_api["tracks"])) if abs(table_api["tracks"][tr]["trend"]) < 1000] assert_that(tracks_ui).is_equal_to(names_api) assert_that(artists_ui).is_equal_to(artists_api) assert_that(trends_ui).is_equal_to(trends_api) assert_that(table_ui["positions"]).is_equal_to(positions_api) assert_that(table_ui["streams"]).is_equal_to(streams_api) @allure.step("Top Charts - click on track and verify track page opened") def click_on_track_and_verify(self, index=1): self.click_on_header() track_el = self.get_element( locator="//*[@id='charts-table-cell-name-{}']/..//*[contains(@href, '/track/')]".format(index), locator_type="xpath", ) self.log.info("index: {}, track names : {}".format(index, track_el)) t = self.get_text(element=track_el) self.click_element(element=track_el) self.trackPage.is_track_page_title_present(track=t) @allure.step("Top Charts - click on artist and verify artist page opened") def click_on_artist_and_verify(self, index=1, tab="spotify"): self.click_on_header() if tab == "spotify": track_el = self.get_element( locator="//*[@id='charts-table-cell-name-{}']/..//*[contains(@href, '/artist/')]".format(index), locator_type="xpath", ) self.log.info("index: {}, track names : {}".format(index, track_el)) t = str(self.get_text(element=track_el)).replace(",", "") self.click_element(element=track_el) self.artist_page.verify_title(title=t) elif tab == self.APPLE_TYPE: track_el = self.get_element( locator="(//*[contains(@href, '/track/')]/ancestor::div/following-sibling::span/div/div)[{}]".format(index), locator_type="xpath", ) ActionChains(self.driver).move_to_element(to_element=track_el).perform() tool = self.get_element( locator="//*[text()='Artist and album pages are not available for the track.']", locator_type="xpath", ) self.ts.markFinal(self.is_element_displayed(element=tool), "tooltip is displayed for artist on apple tab") @allure.step("Top Charts - verify sorting") def verify_sorting(self, column, dsp): elements_desc = [] elements_asc = [] first_position = 1 last_position = int(self.get_last_position() / 2) list_range = list(range(first_position, last_position)) if column == "positions": if dsp == self.APPLE_TYPE: self.click_element(locator="charts-table-cell-position") elements_asc = self.get_from_table("position") self.click_element(locator="charts-table-cell-position") elements_desc = self.get_from_table("position") else: self.click_element(locator="charts-table-cell-position") elements_desc = self.get_from_table("position") self.click_element(locator="charts-table-cell-position") elements_asc = self.get_from_table("position") elif column == "trends": self.click_element(locator="charts-table-cell-trend") for r in list_range: if self.get_position_trends_for_index(r) != "": elements_desc.append(int(self.get_position_trends_for_index(r))) self.click_element(locator="charts-table-cell-trend") for r in list_range: if self.get_position_trends_for_index(r) != "": elements_asc.append(int(self.get_position_trends_for_index(r))) elements_asc.reverse() elif column == "names": if dsp == self.APPLE_TYPE: self.click_element(locator="charts-table-cell-name") elements_asc = self.get_track_names() self.click_element(locator="charts-table-cell-name") elements_desc = self.get_track_names() else: self.click_element(locator="charts-table-cell-name") elements_desc = self.get_track_names() self.click_element(locator="charts-table-cell-name") elements_asc = self.get_track_names() elements_desc = [str(e).split("\n")[0].split(" ")[0].lower() for e in elements_desc][-5:-1] elements_asc = [str(e).split("\n")[0].split(" ")[0].lower() for e in elements_asc][-5:-1] elif column == "streams": self.click_element(locator="charts-table-cell-streams") elements_desc = self.get_from_table(column) self.click_element(locator="charts-table-cell-streams") elements_asc = self.get_from_table(column) if column not in ["names", "trends"]: elements_asc = elements_asc[: elements_asc.index(min(elements_asc))] elements_desc = elements_desc[: elements_desc.index(min(elements_desc))] self.ts.markFinal(elements_desc == sorted(elements_desc, reverse=True), "{} sorted desc: {}".format(column, elements_desc)) self.ts.markFinal(elements_asc == sorted(elements_asc), "{} sorted asc: {}".format(column, elements_asc)) else: if column == "names": translationTable = str.maketrans("éàèùâêîôûç", "eaeuaeiouc") elements_desc = [e.translate(translationTable) for e in elements_desc] elements_asc = [e.translate(translationTable) for e in elements_asc] self.ts.markFinal( elements_desc == sorted(elements_desc, reverse=True) or elements_desc == natsorted(elements_desc, reverse=True), "{} sorted desc: {}".format(column, elements_desc), ) self.ts.markFinal( elements_asc == sorted(elements_asc) or elements_asc == natsorted(elements_asc), "{} sorted asc: {}".format(column, elements_asc), ) @allure.step("Top Charts - get from table column values") def get_from_table(self, column): elements = self.get_elements(locator="//*[contains(@id, 'charts-table-cell-{}-')]".format(column), locator_type="xpath") if column == "streams": values = [int(str(self.get_text(element=e)).replace(",", "")) for e in elements] elif column == "position": values = [int(self.get_text(element=e)) for e in elements] else: values = [self.get_text(element=e) for e in elements] return values @allure.step("Top Charts - get all from apple top 100 table") def get_all_from_table_apple(self, count=100): first_position = 1 last_position = self.get_last_position() names = [] trends = [] positions = [] self.wait_for_chart_table() while last_position <= count: for r in list(range(first_position, last_position + 1)): names.append(self.get_track_names_for_index(r)) trends.append(self.get_position_trends_for_index(r)) positions.append(self.get_track_positions_for_index(r)) self.log.info("names: {}, \ntrends: {}".format(names, trends)) if last_position == count: break self.scroll_to_last_position() first_position = last_position + 1 last_position = self.get_last_position() self.page_has_loaded() if count == (100 or 200): self.ts.markFinal(len(names) == count, "count names: {}".format(len(names))) self.ts.markFinal(len(trends) == count, "count trends: {}".format(len(trends))) ui = [zip(positions, trends, names), {"positions": positions, "trends": trends, "names": names}] self.log.info("from table: {}".format(ui[1])) return ui @allure.step("Top Charts - compare ui and exported csv file") def compare_ui_and_csv(self, market, token): spotify = "Spotify" dsp = spotify csv = self.export_file(market, token) csv_positions = csv["Track Position"].to_list() csv_is_sony = csv["Is Sony?"].to_list() csv_tracks = csv["Track Name"].to_list() csv_tracks = [c[:5] for c in csv_tracks] csv_artists = csv["Artist"].to_list() csv_trends = csv["Position Trend"].to_list() if self.get_attribute_value(*self.locator(self.top_charts_locators, "{}-tab".format(self.APPLE_TYPE)), attribute="data-selected") == "selected": dsp = "Apple Music" if dsp == spotify: ui = self.get_all_from_table()[1] self.ts.markFinal( csv["Streams data"].to_list() == ui["streams"], "column: {} csv: {} and\n ui: {} match".format("STREAMS", csv["Streams data"].to_list(), ui["streams"]), ) else: ui = self.get_all_from_table_apple()[1] tracks = [str(n).split("\n")[0][:5] for n in ui["names"]] artists = [str(n).replace("SONY", "").split("\n")[1] for n in ui["names"]] artists_ui = [] for a in artists: if a != "": artists_ui.append(a) csv_trends = [str(t).replace("NEW", "").replace("Re-entry", "").replace("-", "") for t in csv_trends] is_sony = [] for n in ui["names"]: if "SONY" in str(n): is_sony.append("yes") else: is_sony.append("no") self.ts.markFinal( csv_positions == ui["positions"], "column: {} csv: {} and\n ui: {} match".format("POSITIONS", csv_positions, ui["positions"]), ) self.ts.markFinal(csv_is_sony == is_sony, "column: {} csv: {} and\n ui: {} match".format("IS SONY?", csv_is_sony, is_sony)) self.ts.markFinal( csv_trends == ui["trends"], "column: {} csv: {} and\n ui: {} match".format("TRENDS", csv_trends, ui["trends"]), ) self.ts.markFinal(csv_tracks == tracks, "column: {} csv: {} and\n ui: {} match".format("TRACK NAMES", csv_tracks, tracks)) self.ts.markFinal( all(a in csv_artists for a in artists_ui), "column: {} csv: {} and\n ui: {} match".format("ARTISTS", csv_artists, artists_ui), ) @allure.step("Top Charts - select spotify chart for date by dd index") def open_spotify_chart_for_date_index(self, param): date_sel = "//*[contains(@id, 'period-dd')]//../*[contains(text(), '/')]" self.wait_for_table_load() dd = self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "charts-period-dd")) self.click_element(element=dd) self.wait_for_element_visible(locator=date_sel, locator_type="xpath") self.wait_for_element_clickable(locator=date_sel, locator_type="xpath") selected_date_element = self.get_elements(locator=date_sel, locator_type="xpath")[param] self.click_on_element_js(element=selected_date_element) self.wait_for_table_load() @allure.step("Top Charts - verify trending info icon") def verify_trending_info_icon(self): info_icon = self.get_element(*self.locator(self.top_charts_locators, "trending_info_icon")) ActionChains(self.driver).move_to_element(to_element=info_icon).perform() hint = self.get_element(locator=self.trackPage.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("Data covers only the Trending Music Videos chart. Source: charts.youtube.com (via Chartmetric).") @allure.step("Top Charts trendingGet chosen trending date") def get_selected_trending_date(self): self.wait_for_element_visible(*self.locator(self.top_charts_locators, "trending_calendar_input")) single_calendar = self.get_element(*self.locator(self.top_charts_locators, "trending_calendar_input")) date_ui = self.get_attribute_value(element=single_calendar, attribute="value") date_ui_modified = datetime.strptime(date_ui, self.trackPage.get_date_format_from_locale()).strftime("%Y-%m-%d") return date_ui_modified @allure.step("Top Charts trending - Selecting first day in previous month") def select_trending_previous_month_first_day_date(self): self.scroll_to_element(*self.locator(self.top_charts_locators, "trending_calendar_input")) self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "trending_calendar_input")) single_calendar = self.get_element(*self.locator(self.top_charts_locators, "trending_calendar_input")) self.click_on_element_js(element=single_calendar) self.wait_for_element_visible(*self.locator(self.top_charts_locators, "trending_calendar_prev_month_picker")) previous_month_picker = self.get_element(*self.locator(self.top_charts_locators, "trending_calendar_prev_month_picker")) self.click_on_element_js(element=previous_month_picker) first_day = self.wait_for_element_visible(*self.locator(self.top_charts_locators, "trending_calendar_first_day_prev_month")) self.click_on_element_js(element=first_day) date_ui = self.get_selected_trending_date() date_url = self.trackPage.parameter_from_url(self.date) assert_that(date_ui).is_equal_to(date_url) return date_url @allure.step("Top Charts trending - check last available trending date color on the datepicker grid") def verify_trending_datepicker_last_available_date_color(self, date): grid_date = datetime.strptime(date, "%Y-%m-%d").strftime("%a %b %d %Y") grid_date_locator = f"//div[@aria-label='{grid_date}']" today = datetime.today().date() self.log.info("Today date: " + str(today)) grid_max_date_el = self.get_element(locator=grid_date_locator, locator_type="xpath") grid_max_date_color = grid_max_date_el.value_of_css_property("color") if date == str(today): assert_that(grid_max_date_color).is_equal_to(self.TRENDING_DATEPICKER_TODAY_MAX_DATE_COLOR) else: assert_that(grid_max_date_color).is_equal_to(self.TRENDING_DATEPICKER_MAX_DATE_COLOR) @allure.step("Top Charts trending - Open trending market dd") def open_trending_market_dd(self): self.wait_for_element_visible(*self.locator(self.top_charts_locators, "trending_market_selector")) self.click_element(*self.locator(self.top_charts_locators, "trending_market_selector")) self.is_element_displayed(*self.locator(self.top_charts_locators, "trending-market_dd_filter")) @allure.step("Top Charts trending - Selecting market") def select_trending_market(self, market): self.scroll_to_element(*self.locator(self.top_charts_locators, "charts-title")) self.wait_for_table_load() self.wait_for_element_visible(*self.locator(self.top_charts_locators, "trending_market_selector")) self.click_element(*self.locator(self.top_charts_locators, "trending_market_selector")) market_item = "//*[contains(@id, 'charts-youtube-market-dd-item')][text()='{}']".format(market) market_item = self.get_element(market_item, "xpath") self.click_on_element_js(market_item) @allure.step("Top Charts trending - get selected market") def get_trending_market(self): market = self.wait_for_element_visible(*self.locator(self.top_charts_locators, "trending_market_selector")) market = self.get_text(element=market) return market @allure.step("Trending markets list present") def is_trending_markets_list_present(self): markets_list_locator = "//*[contains(@id, 'top-charts-youtube-market-dd-item-')][contains(@id, 'label')]" markets_list = self.get_elements(locator=markets_list_locator, locator_type="xpath") for market in markets_list: market_is_present = self.is_element_displayed(element=market) assert_that(market_is_present).is_true() @allure.step("Trending markets dd - get markets list") def get_trending_markets_list(self): markets_list_locator = "//*[contains(@id, 'top-charts-youtube-market-dd-item-')][contains(@id, 'label')]" markets_list = self.get_elements(locator=markets_list_locator, locator_type="xpath") markets = [] for market in markets_list: market_name = self.get_text(market) markets.append(market_name) return markets @allure.step("Trending markets dd elements verification") def trending_market_dd_elements_verification(self): markets_list_locator = "//*[contains(@id, 'top-charts-youtube-market-dd-item-')][contains(@id, 'label')]" dividing_line_locator = "//*[@id='top-charts-youtube-market-dd-item-9']/div[2]" markets_list = self.get_elements(locator=markets_list_locator, locator_type="xpath") self.log.info("Markets elements: " + str(markets_list)) markets = [self.get_text(element=a) for a in markets_list] dividing_line = self.is_element_present(locator=dividing_line_locator, locator_type="xpath") top_10_markets = markets[:9] other_markets_list = markets[10:] assert_that(dividing_line).is_true() assert_that(top_10_markets).is_equal_to(AppConfig.get("trending_top_markets")) assert_that(other_markets_list).is_equal_to(AppConfig.get("trending_other_markets")) assert_that(other_markets_list).is_sorted() @allure.step("Trending markets dd selected market verification") def trending_market_dd_selected_market_verification(self, market): market_locator = f"(//*[contains(text(), '{market}')])[3]" market = self.get_element(locator=market_locator, locator_type="xpath") market_font_weight = market.value_of_css_property("font-weight") assert_that(market_font_weight).is_equal_to("800") @allure.step("Trending markets dd - enter search value") def trending_market_dd_enter_search_value(self, text): self.wait_for_element_visible(*self.locator(self.top_charts_locators, "trending_market_selector")) self.clear_text(*self.locator(self.top_charts_locators, "trending-market_dd_filter")) self.send_text(text, *self.locator(self.top_charts_locators, "trending-market_dd_filter")) @allure.step("Filter clear icon is present") def trending_market_dd_clear_icon_is_present(self): self.wait_for_element_visible(*self.locator(self.top_charts_locators, "trending-market_dd_clear_icon")) is_present = self.is_element_present(*self.locator(self.top_charts_locators, "trending-market_dd_clear_icon")) assert_that(is_present).is_true() @allure.step("Trending markets dd - clear text") def trending_markets_clear_text(self): self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "trending-market_dd_clear_icon")) self.click_element(*self.locator(self.top_charts_locators, "trending-market_dd_clear_icon")) @allure.step("Top Charts trending - click export") def click_top_charts_trending_export(self): self.scroll_to_element(*self.locator(self.top_charts_locators, "trending_export_btn")) export = self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "trending_export_btn")) self.click_on_element_js(element=export) self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "trending_export_btn")) @allure.step("Top Charts trending - set date in calendar") def change_trending_date(self, d): self.scroll_to_element(*self.locator(self.top_charts_locators, "trending_calendar_input")) self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "trending_calendar_input")) single_calendar = self.get_element(*self.locator(self.top_charts_locators, "trending_calendar_input")) self.click_on_element_js(element=single_calendar) self.send_text(data=d.replace("/", ""), element=single_calendar) self.send_text(data=Keys.ENTER, element=single_calendar) date_ui = self.get_selected_trending_date() assert_that(date_ui).is_equal_to(datetime.strptime(d, self.trackPage.get_date_format_from_locale()).strftime("%Y-%m-%d")) @allure.step("Top Charts - table filtering") def top_charts_tables_filtering(self, dsp, text): self.wait_for_element_clickable(*self.locator(self.top_charts_locators, f"{dsp}-filter")) self.clear_text(*self.locator(self.top_charts_locators, f"{dsp}-filter")) self.send_text(text, *self.locator(self.top_charts_locators, f"{dsp}-filter")) self.click_element(*self.locator(self.top_charts_locators, "charts-spotify-filter-input-search-icon")) @allure.step("Top Charts - YT Trending verify trending export button") def verify_export_button(self, button="trending", present=True): self.scroll_to_element(*self.locator(self.top_charts_locators, f"{button}_export_btn")) if not present: button_export = self.is_element_displayed(*self.locator(self.top_charts_locators, f"{button}_export_btn")) assert_that(button_export).is_equal_to(present) else: button_export = self.wait_for_element_clickable(*self.locator(self.top_charts_locators, f"{button}_export_btn")) color_before = button_export.value_of_css_property("background-color") self.hover_on_element(element=button_export) color_after = button_export.value_of_css_property("background-color") cursor = button_export.value_of_css_property("cursor") assert_that(cursor).is_equal_to("pointer") assert_that(color_before).is_not_equal_to(color_after) @allure.step("Top Charts - get cell by index value from table table") def get_cell_value_for_index(self, cell, index): loc = f"charts-table-cell-{cell}-{index}" if int(str(index)[-1]) == 0: self.scroll_to_element(loc, "id") value = self.get_text(loc).strip() self.log.info(f"{cell} {index}: {value}") return value @allure.step("Top Charts - Shazam tab - get cell by index value from table table") def get_cell_value_shazam_for_index(self, cell, index): loc = f"charts-shazam-cell-{cell}-{index}" if str(index)[-1] == "0": self.scroll_to_element(loc, "id") value = self.get_text(loc).strip() self.log.info(f"{cell} {index}: {value}") return value @allure.step("Top Charts - Trending tab - get all from table") def get_all_from_table_trending(self): date = self.get_selected_trending_date() market = self.trackPage.parameter_from_url(self.trackPage.market) count = len(self.api_client.get_youtube_full_trend(market, date)) first_position = 1 last_position = self.get_last_position() positions = [] trends = [] titles = [] peak_positions = [] peak_dates = [] on_chart_days = [] while last_position <= count: for r in list(range(first_position, last_position + 1)): positions.append(int(self.get_cell_value_for_index("position", r))) trends.append(int(self.get_cell_value_for_index("trend", r)) if self.get_cell_value_for_index("trend", r) != "" else 0) titles.append(self.get_cell_value_for_index("title", r)) peak_positions.append(int(self.get_cell_value_for_index("peak-position", r))) peak_dates.append(self.get_cell_value_for_index("peak-position-date", r)) on_chart_days.append(int(self.get_text(f"//*[@id='charts-table-cell-peak-position-date-{r}'][2]", "xpath"))) self.log.info("titles: {}, \ntrends: {}, \npositions: {}".format(titles, trends, positions)) if last_position == count: break self.scroll_to_last_position() first_position = last_position + 1 last_position = self.get_last_position() self.page_has_loaded() ui = {"positions": positions, "trends": trends, "titles": titles, "peak_positions": peak_positions, "peak_dates": peak_dates, "on_chart_days": on_chart_days} self.log.info("from table: {}".format(ui)) return ui @allure.step("Top Charts - Trending tab - verify export") def trending_tab_verify_export(self): date_trending = self.get_selected_trending_date() date_trending = datetime.strptime(str(date_trending), "%Y-%m-%d").strftime(self.trackPage.get_date_file_format_from_locale()) market = self.trackPage.parameter_from_url(self.trackPage.market) table_ui = self.get_all_from_table_trending() button_export = self.get_element(*self.locator(self.top_charts_locators, "trending_export_btn")) self.click_on_element_js(element=button_export) file_path = f"""http://{CoreConfig.SELENOID_HOST}:4444/download/{self.driver.session_id}/{date_trending} - {market.upper()} - Trending.csv""" self.log.info(f"file path: {file_path}") position_column = "Position #" columns = [position_column, "Position Trend", "Title", "Peak, Lifetime Position #", "Peak, Lifetime Position # Date", "On Chart, Lifetime Days"] data = self.trackPage.read_from_csv(file_path) self.log.info(f"pandas data: {data}") file = {} for c in list(data.columns): file[c] = data.get(c).to_list() self.log.info(f"file: {file}") # verify file_columns = list(data.columns) assert_that(file_columns).is_equal_to(columns) assert_that(file[position_column]).is_sorted() assert_that([t.split("\n")[0][:5] for t in table_ui["titles"]]).is_equal_to([t[:5] for t in file["Title"]]) assert_that(table_ui["positions"]).is_equal_to(file["Position #"]) assert_that(table_ui["trends"]).is_equal_to([abs(int(str(f).replace("Re-Entry", "0").replace("New Entry", "0"))) for f in file["Position Trend"]]) assert_that(table_ui["peak_positions"]).is_equal_to(file["Peak, Lifetime Position #"]) assert_that([datetime.strptime(d, self.trackPage.get_date_format_from_locale()).date() for d in table_ui["peak_dates"]]).is_equal_to([datetime.strptime(d, self.trackPage.get_date_format_from_locale()).date() for d in file["Peak, Lifetime Position # Date"]]) assert_that(table_ui["on_chart_days"]).is_equal_to(file["On Chart, Lifetime Days"]) @allure.step("Top Charts - Trending tab - open popup") def open_trending_popup(self, position=1): position_icon = f"//*[contains(@id, 'position-{position}')]/..//*[contains(@class, 'position')]" trending_popup_title_locator = "youtube-trending-modal-window-title" icon = self.wait_for_element_clickable(position_icon, "xpath") self.click_element(element=icon) assert_that(self.is_element_displayed(trending_popup_title_locator)).is_true() @allure.step("Trending Details popup - verify number of the lines and color") def verify_lines_number_trending_popup(self, lines_color, expected_number=1): line_loc = f"//*[contains(@class, 'highcharts-series-group')]/*[@class='highcharts-series highcharts-series-{expected_number - 1} highcharts-spline-series']" line_locs = [line_loc.format(n) for n in range(expected_number)] line_els = [self.get_element(locator=loc, locator_type="xpath") for loc in line_locs] assert_that(len(line_els)).is_equal_to(expected_number) for line in line_els: for color in lines_color: line_colour_graph = line.value_of_css_property("color") assert_that(line_colour_graph).is_equal_to(color) @allure.step("Trending Details popup - verify axis") def verify_axes_trending_popup(self): loc = "//*[contains(@class, 'highcharts-') and contains(@class, '-title')]" self.wait_for_element_visible(loc, "xpath") els = self.get_elements(loc, "xpath") axes_text = [self.get_text(element=e) for e in els] assert_that(axes_text[:2]).is_equal_to(["POSITION ON CHART", "DATE"]) @allure.step("Trending Details popup - verify legend") def verify_legend_trending_popup(self): legend_text_els = self.get_elements(locator="//*[contains(@id, 'youtube-trending-modal-window-chart-legend-')]", locator_type="xpath") legend_text = [self.get_text(element=el) for el in legend_text_els] legend_peak_label = self.get_element("youtube-trending-modal-window-chart-0-peak-label") legend_min_label = self.get_element("youtube-trending-modal-window-chart-0-min-label") legend_peak_icon = self.is_element_present("youtube-trending-modal-window-chart-0-peak-icon") legend_min_icon = self.is_element_present("youtube-trending-modal-window-chart-0-min-icon") legend_text.append(self.get_text(element=legend_peak_label)) legend_text.append(self.get_text(element=legend_min_label)) assert_that(legend_text).is_equal_to(["POSITION", "ON CHART", "Peak", "Minimum"]) assert_that(legend_peak_icon).is_true() assert_that(legend_min_icon).is_true() @allure.step("Trending Details popup - get tooltip info") def get_tooltip_trending_popup(self, param=365 * 2): e = self.get_element(*self.locator(self.top_charts_locators, "trending-popup-chart")) 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)) tooltips = [] for t in range(0, width, step): e = self.get_element(*self.locator(self.top_charts_locators, "trending-popup-chart")) ActionChains(self.driver).move_to_element_with_offset(to_element=e, xoffset=t, yoffset=height).perform() tooltip_el = self.get_element(locator="(//iframe/following-sibling::div/*)[last()]", locator_type="xpath") text = str(self.get_text(element=tooltip_el)) if text not in [None, "None", ["None"], [None]]: if text.strip() not in tooltips: tooltips.append(text.strip()) self.log.info("tooltip text: {}".format(text)) self.log.info("trending popup tooltip content: {}".format(tooltips[1:])) return set(tooltips[1:]) @allure.step("Trending Details popup - verify tooltip in correspondence with API response") def verify_tooltip_trending_popup(self, ui_tooltip, video_id, market): ui_tooltip_text = [str(t).replace("\nMinimum", "").replace("\nPeak", "").split("\n") for t in ui_tooltip] # tooltip format verification for i in range(len(ui_tooltip_text)): assert_that(datetime.strptime(ui_tooltip_text[i][0].split(", ")[1], self.trackPage.get_date_format_from_locale()).strftime("%A")).is_equal_to(ui_tooltip_text[i][0].split(", ")[0]) assert_that("Position" in ui_tooltip_text[i]).is_true() assert_that(ui_tooltip_text[i][-1]).contains("of") assert_that(ui_tooltip_text[i][-1]).contains("videos") self.log.info(f"UI tooltip: {ui_tooltip_text}") # ui and api data for comparison ui_tooltip_formatted = [] for i in range(len(ui_tooltip_text)): ui_tooltip = { "weekday": datetime.strptime(ui_tooltip_text[i][0].split(", ")[1], self.trackPage.get_date_format_from_locale()).strftime("%A"), "date": datetime.strptime(ui_tooltip_text[i][0].split(", ")[1], self.trackPage.get_date_format_from_locale()).date(), "position": str(ui_tooltip_text[i][-1]).split(" of")[0], "videos": str(ui_tooltip_text[i]).replace(" videos']", "").split("of ")[1], } ui_tooltip_formatted.append(ui_tooltip) self.log.info(f"UI tooltip formatted: {ui_tooltip_formatted}") start = self.trackPage.get_calendar_start_date() end = self.trackPage.get_calendar_end_date() api_response = self.api_client.get_charts_youtube_video_positions(video_id=video_id, market=market, start=start, end=end) api_tooltip_formatted = [] for i in range(len(api_response["items"])): api_tooltip = { "weekday": datetime.strptime(api_response["items"][i]["date"], "%Y-%m-%d").strftime("%A"), "date": datetime.strptime(api_response["items"][i]["date"], "%Y-%m-%d").strftime("%m/%d/%y"), "position": api_response["items"][i]["position"], "total_positions": api_response["chart"]["total_positions"], } api_tooltip_formatted.append(api_tooltip) self.log.info("API tooltip: " + str(api_tooltip_formatted)) # position verification for u in range(len(ui_tooltip_formatted)): for a in range(len(api_tooltip_formatted)): if ui_tooltip_formatted[u]["date"] == api_tooltip_formatted[a]["date"]: assert_that(ui_tooltip_formatted[u]["position"]).is_equal_to(api_tooltip_formatted[a]["position"]) @allure.step("Trending Details popup - verify peak and minimum graph values") def verify_peak_minimum_tooltip_trending_popup(self, ui_tooltip): ui_tooltip_text = [str(t).split(" of")[0].split("\n") for t in ui_tooltip] positions = [ui_tooltip_text[i][-1] for i in range(len(ui_tooltip_text))] positions = [int(p) for p in positions] self.log.info("Positions: " + str(positions)) peak_position = min(positions) minimum_position = max(positions) for t in range(len(ui_tooltip_text)): if ui_tooltip_text[t][2] == "Peak": assert_that(int(ui_tooltip_text[t][-1])).is_equal_to(peak_position) elif ui_tooltip_text[t][2] == "Minimum": assert_that(int(ui_tooltip_text[t][-1])).is_equal_to(minimum_position) @allure.step("Trending Details popup - verify peak and minimum graph values") def verify_trending_popup_datepicker_minimized(self): period_label_loc = "//div[@id='modal-content']//span[contains(text(), 'period')]" is_period_label_displayed = self.is_element_present(locator=period_label_loc, locator_type="xpath") datepicker_el = self.get_element(*self.locator(self.top_charts_locators, "trending-popup-datepicker")) is_datepicker_displayed = self.is_element_displayed(element=datepicker_el) is_datepicker_icon_displayed = self.is_element_displayed(*self.locator(self.top_charts_locators, "trending-popup-datepicker-icon")) assert_that(is_period_label_displayed).is_true() assert_that(is_datepicker_displayed).is_true() assert_that(is_datepicker_icon_displayed) # dates format verification start = str(self.get_text(element=datepicker_el).split("–")[0]) end = str(self.get_text(element=datepicker_el).split("–")[1]) start_date = datetime.strptime(start, self.trackPage.get_date_format_from_locale()) end_date = datetime.strptime(end, self.trackPage.get_date_format_from_locale()) assert_that(start_date).is_instance_of(datetime) assert_that(end_date).is_instance_of(datetime) @allure.step("Trending Details popup - Retrieving start date from calendar") def get_trending_popup_datepicker_start_date(self): self.wait_for_element_visible(*self.locator(self.top_charts_locators, "trending-popup-datepicker")) date_raw = str(self.get_text(*self.locator(self.top_charts_locators, "trending-popup-datepicker"))).split("–")[0] return datetime.strptime(date_raw, self.trackPage.get_date_format_from_locale()).strftime("%Y-%m-%d") @allure.step("Trending Details popup - Retrieving end date from calendar") def get_trending_popup_datepicker_end_date(self): self.wait_for_element_visible(*self.locator(self.top_charts_locators, "trending-popup-datepicker")) date_raw = str(self.get_text(*self.locator(self.top_charts_locators, "trending-popup-datepicker"))).split("–")[1] print(date_raw) return datetime.strptime(date_raw, self.trackPage.get_date_format_from_locale()).strftime("%Y-%m-%d") @allure.step("Trending Details popup - swipe to date") def trending_popup_datepicker_swipe_to_date(self, date_to_swipe, date_from_swipe, swipe="prev"): date_to_swipe = datetime.strptime(date_to_swipe, "%Y-%m-%d").date() date_from_swipe = datetime.strptime(date_from_swipe, "%Y-%m-%d").date() datepicker_el = self.get_element(*self.locator(self.top_charts_locators, "trending-popup-datepicker")) self.click_element(element=datepicker_el) swiping_arrow_loc = f"//*[@class='DayPicker-NavButton DayPicker-NavButton--{swipe}']" swiping_arrow = self.get_element(locator=swiping_arrow_loc, locator_type="xpath") if date_to_swipe.day > date_from_swipe.day: months = rrule.rrule(rrule.MONTHLY, dtstart=date_to_swipe, until=date_from_swipe).count() - 2 else: months = rrule.rrule(rrule.MONTHLY, dtstart=date_to_swipe, until=date_from_swipe).count() - 1 self.log.info("Numer of months: " + str(months)) for m in range(months): self.click_on_element_js(element=swiping_arrow) calendar_month_year_locator = "(//div[@class='DayPicker-Caption'])[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.strptime(str(date_to_swipe), "%Y-%m-%d").strftime("%B %Y") assert_that(date_to_count_month_year).is_equal_to(calendar_month_year_text) @allure.step("Trending Details popup - select custom period") def trending_popup_datepicker_select_custom_period(self, date_from_swipe, start_date, end_date, swipe_start, swipe_end): self.trending_popup_datepicker_swipe_to_date(date_to_swipe=start_date, date_from_swipe=date_from_swipe, swipe=swipe_start) start_date_f = datetime.strptime(start_date, "%Y-%m-%d").strftime("%a %b %d %Y") end_date_f = datetime.strptime(end_date, "%Y-%m-%d").strftime("%a %b %d %Y") start_date_loc = f"//*[@aria-label='{start_date_f}']" end_date_loc = f"//*[@aria-label='{end_date_f}']" self.click_element(locator=start_date_loc, locator_type="xpath") self.trending_popup_datepicker_swipe_to_date(date_to_swipe=end_date, date_from_swipe=start_date, swipe=swipe_end) self.click_element(locator=end_date_loc, locator_type="xpath") self.verify_trending_popup_datepicker_period_applied(start_date=start_date, end_date=end_date) @allure.step("Trending Details popup - verify today date style") def verify_trending_popup_datepicker_today_date(self, youtube=True): datepicker_el = self.get_element(*self.locator(self.top_charts_locators, "trending-popup-datepicker")) self.click_element(element=datepicker_el) today_date_loc = "//*[contains(@class, 'DayPicker-Day--today')]" today_date_el = self.get_element(locator=today_date_loc, locator_type="xpath") today_day = self.get_text(element=today_date_el) today = datetime.today().date() assert_that(today_day).is_equal_to(str(today.day)) if youtube: today_day_color = today_date_el.value_of_css_property("color") assert_that(today_day_color).is_equal_to("rgba(255, 60, 129, 1)") @allure.step("Trending Details popup - verify future period selecting") def verify_trending_popup_datepicker_future_period(self): datepicker_el = self.get_element(*self.locator(self.top_charts_locators, "trending-popup-datepicker")) self.click_element(element=datepicker_el) future_date_loc = "//*[contains(@class, 'DayPicker-Day--today')]/following-sibling::div[1]" future_date_el = self.get_element(locator=future_date_loc, locator_type="xpath") future_date_day = self.get_text(element=future_date_el) today = datetime.today().date() assert_that(int(future_date_day)).is_equal_to(int(today.day) + 1) is_future_date_disabled = future_date_el.get_attribute("aria-disabled") self.log.info(f"Is future date disabled: {is_future_date_disabled}") assert_that(is_future_date_disabled).is_true() @allure.step("Trending Details popup - verify period start and end dates") def verify_trending_popup_datepicker_start_end_date(self, start_date, end_date): colors = ["rgba(0, 0, 0, 1)", "rgba(0, 0, 0, 0)"] datepicker_el = self.get_element(*self.locator(self.top_charts_locators, "trending-popup-datepicker")) self.click_element(element=datepicker_el) start_date_loc = "//*[contains(@class, 'DayPicker-Day--firstDate DayPicker-Day--selected')]" end_date_loc = "//*[contains(@class, 'DayPicker-Day--lastDate DayPicker-Day--selected')]" today = datetime.today().date() self.trending_popup_datepicker_swipe_to_date(date_to_swipe=end_date, date_from_swipe=str(today)) end_date_el = self.get_element(locator=end_date_loc, locator_type="xpath") end_date_color = end_date_el.value_of_css_property("background-color") self.trending_popup_datepicker_swipe_to_date(date_to_swipe=start_date, date_from_swipe=end_date) start_date_el = self.get_element(locator=start_date_loc, locator_type="xpath") start_date_color = start_date_el.value_of_css_property("background-color") assert_that(colors).contains(str(end_date_color)) assert_that(colors).contains(str(start_date_color)) @allure.step("Trending Details popup - collapse datepicker grid") def trending_popup_collapse_datepicker_grid(self): dp = self.wait_for_element_visible("youtube-trending-modal-window-title") title = self.get_text(element=dp) self.click_on_element_js(element=dp) assert_that(title).is_equal_to("Trending Details") @allure.step("Trending Details popup - verify datepicker is closed") def verify_trending_popup_datepicker_closed(self): dp_grid_loc = "//*[@class='DayPicker']" is_dp_grid_opened = self.is_element_displayed(locator=dp_grid_loc, locator_type="xpath") assert_that(is_dp_grid_opened).is_false() @allure.step("Trending Details popup - verify calendar predefined periods") def verify_trending_popup_datepicker_predefined_periods(self): no_data_locator = "//*[text()='No data available.']" for p in self.trackPage.dp_predefined_periods: # ["2-weeks", "4-weeks", "8-weeks", "12-weeks", "26-weeks", "1-year"] count_label_locator = "youtube-trending-modal-window-day-count-label" days_count_before = self.get_text(count_label_locator) xaxis_before = self.trackPage.graph_get_xaxis() xaxis_before_last = xaxis_before.index("DATE") self.trackPage.select_predefined_period(p) days_count_after = self.get_text(count_label_locator) assert_that(days_count_before).is_equal_to(days_count_after) no_data = self.is_element_displayed(locator=no_data_locator, locator_type="xpath") if no_data is False: xaxis_after = self.trackPage.graph_get_xaxis() xaxis_after_last = xaxis_after.index("DATE") assert_that(xaxis_before[:xaxis_before_last]).is_not_equal_to(xaxis_after[:xaxis_after_last]) if p == "4-weeks": dp = self.wait_for_element_visible(*self.locator(self.top_charts_locators, "trending-popup-datepicker-icon")) self.click_on_element_js(element=dp) p_el_4_weeks = self.wait_for_element_visible(locator=f"//*[contains(@id, '-day-picker-{p}')]", locator_type="xpath") p_el_2_weeks = self.wait_for_element_visible(locator="//*[contains(@id, '-day-picker-2-weeks')]", locator_type="xpath") color_2 = p_el_2_weeks.value_of_css_property("background-color") color_4 = p_el_4_weeks.value_of_css_property("background-color") assert_that(color_2).is_not_equal_to(color_4) self.trending_popup_collapse_datepicker_grid() @allure.step("Trending Details popup - verify period applied to graph") def verify_trending_popup_datepicker_period_applied(self, start_date, end_date): xaxis_all = self.trackPage.graph_get_xaxis() xaxis = xaxis_all[: xaxis_all.index("DATE")] start_date = datetime.strptime(start_date, "%Y-%m-%d").date() end_date = datetime.strptime(end_date, "%Y-%m-%d").date() period_days = (end_date - start_date).days + 1 start_date_g = datetime.strptime(str(start_date), "%Y-%m-%d").strftime("%d %b").lower() start_date_graph = xaxis[0].lower() if period_days > 14: end_date = end_date - timedelta(days=1) end_date_g = datetime.strptime(str(end_date), "%Y-%m-%d").strftime("%d %b").lower() end_date_graph = xaxis[-1].lower() assert_that(start_date_g).is_equal_to(start_date_graph) assert_that(end_date_g).is_equal_to(end_date_graph) @allure.step("Top Charts - Trending tab - Popup - verify export") def trending_tab_popup_verify_export(self, market, popup_index): video_title = self.get_text("youtube-trending-modal-window-video-main-info-videos-title") market_code = self.trackPage.parameter_from_url(self.trackPage.market) positions_api = self.get_trending_popup_positions_api(popup_index) button_export = self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "trending_popup_export_btn")) self.click_element(element=button_export) file_path = f"""http://{CoreConfig.SELENOID_HOST}:4444/download/{self.driver.session_id}/Trending Position over time - {video_title} - {market_code.upper()}.csv""" self.log.info(f"file path: {file_path}") columns = ["Date", "Country", "Video Title", "Position"] data = self.trackPage.read_from_csv(file_path) self.log.info(f"pandas data: {data}") file = {} for c in list(data.columns): file[c] = data.get(c).to_list() self.log.info(f"file: {file}") # verify file_columns = list(data.columns) date_column_values = [datetime.strptime(f, self.trackPage.get_date_format_from_locale()).date() for f in file["Date"]] start = self.trackPage.get_calendar_start_date() start = datetime.strptime(start, "%Y-%m-%d").date() date_range = [] days_count = self.trackPage.graph_get_count_days_from_calendar() for i in range(days_count): d = start + timedelta(days=i) date_range.append(d) assert_that(file_columns).is_equal_to(columns) assert_that(date_column_values).is_sorted() assert_that(date_column_values).is_equal_to(date_range) assert_that({market}).is_equal_to(set(file["Country"])) assert_that({video_title}).is_equal_to(set(file["Video Title"])) assert_that(set(positions_api)).is_equal_to(set([f for f in file["Position"] if f != "N/A"])) @allure.step("Top Charts - verify export inactive") def verify_export_button_inactive(self, button="trending_popup"): self.wait_for_element_visible(*self.locator(self.top_charts_locators, f"{button}_export_btn")) export = self.get_element(*self.locator(self.top_charts_locators, f"{button}_export_btn")) color_before = export.value_of_css_property("background-color") assert_that(color_before).is_equal_to("rgba(253, 253, 254, 1)") @allure.step("Top Charts - Trending Popup - get min max positions") def get_trending_popup_positions_api(self, position=1): date = self.trackPage.parameter_from_url(self.date) market = self.trackPage.parameter_from_url(self.trackPage.market) video_id = self.api_client.get_youtube_full_trend(market, date)[position - 1]["video_id"] start = self.trackPage.get_calendar_start_date() end = self.trackPage.get_calendar_end_date() positions_api = self.api_client.get_charts_youtube_video_positions(video_id, market, start, end)["items"] positions_api = [i["position"] for i in positions_api] return positions_api @allure.step("Top Charts - Shazam - get date from UI") def get_shazam_date_ui(self): date_locator = "//input[contains(@placeholder, '/')]" date_el = self.wait_for_element_visible(date_locator, "xpath") date_text = self.get_attribute_value(element=date_el, attribute="value") date_text = datetime.strptime(date_text, self.trackPage.get_date_format_from_locale()).strftime("%Y-%m-%d") return date_text @allure.step("Top Charts - Shazam - change market") def select_shazam_market(self, market): self.wait_for_table_load() self.wait_for_element_visible(*self.locator(self.top_charts_locators, "shazam_market_selector")) self.click_element(*self.locator(self.top_charts_locators, "shazam_market_selector")) market_item = "//*[contains(@id, 'charts-shazam-market-dd-item')][text()='{}']".format(market) market_item = self.get_element(market_item, "xpath") self.click_on_element_js(market_item) time.sleep(2) self.wait_for_table_load() @allure.step("Top Charts - Shazam - get selected market") def get_shazam_market(self): market = self.wait_for_element_visible(*self.locator(self.top_charts_locators, "shazam_market_selector")) market = self.get_text(element=market) return market @allure.step("Top Charts - Shazam - change city") def select_shazam_city(self, city): self.wait_for_table_load() self.wait_for_element_visible(*self.locator(self.top_charts_locators, "shazam_city_selector")) self.click_element(*self.locator(self.top_charts_locators, "shazam_city_selector")) market_item = f"//*[@id='top-charts-shazam-city-dd']//../*[text()='{city}']" market_item = self.get_element(market_item, "xpath") self.click_on_element_js(market_item) @allure.step("Top Charts - Shazam - get city") def get_shazam_city(self): self.wait_for_table_load() city_el = self.wait_for_element_visible(*self.locator(self.top_charts_locators, "shazam_city_selector")) city = self.get_text(element=city_el) return city @allure.step("Top Charts - Shazam tab - verify export") def shazam_tab_verify_export(self, market_code="Global"): date_ui = self.trackPage.parameter_from_url(self.date) market_api = "_gl" city_code = "" if market_code != "Global": market_api = market_code market_code = market_api.upper() elif self.market in self.get_url(): market_api = self.trackPage.parameter_from_url(self.market) market_code = market_api.upper() if self.city in self.get_url(): city_code = self.trackPage.parameter_from_url(self.city) city_name = self.get_shazam_city() api_data = self.api_client.get_shazam_charts(market=market_api, date=date_ui, city=city_code)["items"] api_data_sorted = sorted(api_data, key=lambda d: d["position"]) button_export = self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "shazam_export_btn")) self.click_element(element=button_export) date_ui = datetime.strptime(date_ui, "%Y-%m-%d").strftime(self.trackPage.get_date_file_format_from_locale()) file_path = f"""http://{CoreConfig.SELENOID_HOST}:4444/download/{self.driver.session_id}/{date_ui} - {market_code.replace("_GL", "Global")} - {city_name} - Shazam Top 200.csv""" self.log.info(f"file path: {file_path}") columns = ["Position #", "Position Trend", "Track", "Artist", "Release Date", "Peak, Lifetime Position #", "Peak, Lifetime Position # Date", "Total, Lifetime Shazams", "On Chart, Lifetime Days"] data = self.trackPage.read_from_csv(file_path) self.log.info(f"pandas data: {data}") file = {} for c in list(data.columns): file[c] = data.get(c).to_list() self.log.info(f"file: {file}") # verify track_len = 3 artists_api = [", ".join(n["name"] for n in t["track"]["artists"])[:track_len] for t in api_data_sorted if "artists" in t["track"].keys()] artists_file = [t[:track_len] for t in file["Artist"] if str(t) != "nan"] translationTable = str.maketrans("éàèùâêîôûç", "eaeuaeiouc") artists_api = [e.translate(translationTable) for e in artists_api] artists_file = [e.translate(translationTable) for e in artists_file] file_columns = list(data.columns) file_release_dates = set([datetime.strptime(d, self.trackPage.get_date_format_from_locale()).strftime(self.trackPage.get_date_format_from_locale()) for d in file["Release Date"] if str(d) != "nan"]) api_release_dates = set([datetime.strptime(t["track"]["release_date"], AppConfig.get("date_formats")["yyyy-mm-dd"]).strftime(self.trackPage.get_date_format_from_locale()) for t in api_data_sorted if t["track"]["release_date"] is not None]) file_peak_date = set([datetime.strptime(d, self.trackPage.get_date_format_from_locale()).strftime(self.trackPage.get_date_format_from_locale()) for d in file["Peak, Lifetime Position # Date"] if str(d) != "nan"]) api_peak_date = set([datetime.strptime(t["peak"]["date"], AppConfig.get("date_formats")["yyyy-mm-dd"]).strftime(self.trackPage.get_date_format_from_locale()) for t in api_data_sorted if "peak" in t.keys() and "date" in t["peak"].keys() and t["peak"]["date"] is not None]) assert_that(file_columns).is_equal_to(columns) assert_that(file["Position #"]).is_sorted() assert_that([int(str(t).replace("nan", "0").replace("New Entry", "10000").replace("Re-entry", "10000")) for t in file["Position Trend"]]).is_equal_to([-t["trend"] for t in api_data_sorted]) assert_that([t[:track_len] for t in file["Track"]]).is_equal_to([t["track"]["name"][:track_len] for t in api_data_sorted]) assert_that(artists_file).is_equal_to(artists_api) assert_that(file_release_dates).is_equal_to(api_release_dates) assert_that([p for p in file["Peak, Lifetime Position #"] if str(p) != "nan"]).is_equal_to([t["peak"]["position"] for t in api_data_sorted if "peak" in t.keys() and "position" in t["peak"].keys()]) assert_that(file_peak_date).is_equal_to(api_peak_date) assert_that([p for p in file["Total, Lifetime Shazams"] if str(p) != "nan"]).is_equal_to([t["shazams"] for t in api_data_sorted if "shazams" in t.keys()]) assert_that([p for p in file["On Chart, Lifetime Days"] if str(p) != "nan"]).is_equal_to([t["days_on_chart"] for t in api_data_sorted if "days_on_chart" in t.keys()]) @allure.step("Top Charts - Shazam tab - sort by column") def sort_by_column(self, dsp, value): if dsp == self.SPOTIFY_TYPE or self.APPLE_TYPE or self.TRENDING_TYPE: column_locator = f"charts-cell-{value}" else: column_locator = f"charts-{dsp}-cell-{value}" column_el = self.wait_for_element_clickable(column_locator) self.click_element(element=column_el) time.sleep(2) @allure.step("Top Charts - Shazam tab - filter by value") def shazam_filter_by(self, value): filter_locator = "top-charts-shazam-filter-input" filter_el = self.wait_for_element_clickable(filter_locator) self.send_text(data=value, element=filter_el) time.sleep(2) self.wait_for_table_load() @allure.step("Top Charts - Shazam tab - get all from table") def get_all_from_table_shazam(self, full=True): count = 200 first_position = 1 last_position = self.get_last_position_shazam() positions = [] trends = [] titles = [] release_date = [] peak_positions = [] peak_dates = [] lifetime_shazam = [] lifetime_days = [] while last_position <= count: for r in list(range(first_position, last_position + 1)): positions.append(int(self.get_cell_value_shazam_for_index("position", r))) trends.append(int(self.get_cell_value_shazam_for_index("trend", r)) if self.get_cell_value_shazam_for_index("trend", r) != "" else 10000) titles.append(self.get_cell_value_shazam_for_index("name", r)) release_date.append(self.get_cell_value_shazam_for_index("release-date", r).replace("N/A", "10000000")) peak_positions.append(int(self.get_cell_value_shazam_for_index("peak-position", r).replace("N/A", "10000000"))) peak_dates.append(self.get_cell_value_shazam_for_index("peak-position-date", r).replace("N/A", "10000000")) lifetime_shazam.append(int(self.get_cell_value_shazam_for_index("shazams", r).replace(",", "").replace("N/A", "10000000"))) lifetime_days.append(int(self.get_cell_value_shazam_for_index("days-on-chart", r).replace("N/A", "10000000").replace(",", ""))) self.log.info("titles: {}, \ntrends: {}, \npositions: {}".format(titles, trends, positions)) if last_position == count or not full: break self.scroll_to_last_position_shazam() first_position = last_position + 1 last_position = self.get_last_position_shazam() self.page_has_loaded() ui = {"positions": positions, "trends": trends, "titles": titles, "release_date": release_date, "peak_positions": peak_positions, "peak_dates": peak_dates, "lifetime_shazam": lifetime_shazam, "lifetime_days": lifetime_days} self.log.info("from table: {}".format(ui)) return ui @allure.step("Top Charts - Shazam tab - verify_sorting") def verify_sorting_shazam(self, column1, column2=None): elements_desc_column1 = [] elements_asc_column1 = [] position, trend, name, release_date, peak_position, peak_position_date, shazams, days_on_chart = "position", "trend", "name", "release-date", "peak-position", "peak-position-date", "shazams", "days-on-chart" locator_column_header = f"charts-shazam-cell-{column1}" if column1 == position: self.click_element(locator=locator_column_header) elements_desc_column1 = self.get_all_from_table_column_shazam(column1) self.click_element(locator=locator_column_header) elements_asc_column1 = self.get_all_from_table_column_shazam(column1) elif column1 == peak_position: self.click_element(locator=locator_column_header) elements_asc_column1 = self.get_all_from_table_column_shazam(column1) self.click_element(locator=locator_column_header) elements_desc_column1 = self.get_all_from_table_column_shazam(column1) elif column1 in [release_date, peak_position, peak_position_date, shazams, days_on_chart]: self.click_element(locator=locator_column_header) elements_desc_column1 = self.get_all_from_table_column_shazam(column1) self.click_element(locator=locator_column_header) elements_asc_column1 = self.get_all_from_table_column_shazam(column1) elif column1 == trend: self.click_element(locator=locator_column_header) elements_asc_column1 = self.get_all_from_table_column_shazam(column1)[:5] elements_asc_column1.reverse() self.click_element(locator=locator_column_header) elements_desc_column1 = self.get_all_from_table_column_shazam(column1)[:5] if column1 not in [name, release_date]: assert_that(elements_asc_column1).described_as(column1).is_sorted() assert_that(elements_desc_column1).described_as(column1).is_sorted(reverse=True) if column2 and column2 != name: elements_column2 = self.get_all_from_table_column_shazam(column2)[:5] self.log.info(f"elements_column2: {elements_column2}") def function(e): return e[0], e[1] two_columns_values = sorted(zip(elements_asc_column1[:5], elements_column2), key=function) self.log.info(f"two_columns_values: {two_columns_values}") assert_that(elements_column2).is_equal_to([e[1] for e in two_columns_values]) @allure.step("Top Charts - Shazam tab - scroll to last position") def scroll_to_last_position_shazam(self): position = self.get_last_position_shazam() self.scroll_to_element(locator="charts-shazam-cell-position-{}".format(position), locator_type="id") @allure.step("Top Charts - Shazam tab - get last position") def get_last_position_shazam(self): last_position = self.get_elements(locator="//*[contains(@id, 'charts-shazam-cell-position-')]", locator_type="xpath")[-1] return int(self.get_text(element=last_position)) @allure.step("Top Charts - Shazam tab - get all from table column") def get_all_from_table_column_shazam(self, column): locator_column = f"//*[contains(@id, 'charts-shazam-cell-{column}-')]" if column == "peak-position": locator_column = f"//*[contains(@id, 'charts-shazam-cell-{column}-') and not(contains(@id, 'date'))]" self.wait_for_element_visible(locator_column, "xpath") values = self.get_elements(locator_column, "xpath") values = [self.get_text(element=v) for v in values] position, trend, release_date, peak_position, peak_position_date, shazams, days_on_chart = "position", "trend", "release-date", "peak-position", "peak-position-date", "shazams", "days-on-chart" if column in [position, trend, peak_position, shazams, days_on_chart]: values = [int(v.replace("N/A", "1000000").replace(",", "")) for v in values if v != ""] elif column in [release_date, peak_position_date]: values = [datetime.strptime(v, self.trackPage.get_date_format_from_locale()).date() for v in values if v != "N/A"] self.log.info(f"values for shazam column: {column}: {values}") return values @allure.step("Top Charts - Shazam tab - open popup with index") def shazam_open_popup(self, position=1): position_locator = f"charts-shazam-cell-position-{position}" popup_title = "top-charts-shazam-modal-window-title" position_el = self.wait_for_element_clickable(position_locator) self.click_element(element=position_el) assert_that(self.is_element_displayed(popup_title)).is_true() @allure.step("Top Charts - Shazam tab - verify popup export") def shazam_tab_verify_popup_export(self, date): market_api = self.trackPage.parameter_from_url(self.market) city_code = "" if self.city in self.get_url(): city_code = self.trackPage.parameter_from_url(self.city) start = self.trackPage.get_calendar_start_date() end = self.trackPage.get_calendar_end_date() market_city = self.get_text("//*[contains(text(), 'Daily Top 200 ')]", "xpath").replace("Daily Top 200 ", "").split(", ") market_name = market_city[0] city_name = market_city[1] track_link = self.wait_for_element_visible("top-charts-shazam-modal-window-track-link") track_name = self.get_text(element=track_link) id = track_link.get_attribute("href").split("/")[-1] if id.isnumeric(): api_shazam_charts = self.api_client.get_shazam_charts(market=market_api, date=date)["items"] isrc = [api_shazam_charts[i]["track"]["isrc"] for i in range(len(api_shazam_charts)) if api_shazam_charts[i]["track"]["id"] == id][0] else: isrc = self.api_client.get_isrc_by_spotify_id(market_api, id)["external_ids"]["isrc"] api_data = self.api_client.get_shazam_charts_positions(market=market_api, city=city_code, isrc=isrc, start=start, end=end)["values"] api_data_sorted = sorted(api_data, key=lambda d: d["date"]) button_export = self.wait_for_element_clickable(*self.locator(self.top_charts_locators, "shazam_popup_export_btn")) self.click_element(element=button_export) file_path = f"""http://{CoreConfig.SELENOID_HOST}:4444/download/{self.driver.session_id}/Shazam Top 200 - Position over time - {track_name} - {market_api.upper().replace('_GL', 'Global')} - {city_name}.csv""" self.log.info(f"file path: {file_path}") columns = ["Date", "Country", "City", "Track", "Position"] data = self.trackPage.read_from_csv(file_path) self.log.info(f"pandas data: {data}") file = {} for c in list(data.columns): file[c] = data.dropna().get(c).to_list() self.log.info(f"file: {file}") # verify file_columns = list(data.columns) file_dates = [datetime.strptime(d, self.trackPage.get_date_format_from_locale()).date() for d in file["Date"]] api_dates = [datetime.strptime(d["date"], "%Y-%m-%d").date() for d in api_data_sorted] assert_that(file_columns).is_equal_to(columns) assert_that(file_dates).is_sorted() assert_that(api_dates).is_subset_of(file_dates) assert_that(set(file["Country"])).is_equal_to({market_name}) assert_that(set(file["City"])).is_equal_to({city_name}) assert_that(set(file["Track"])).is_equal_to({track_name}) assert_that(file["Position"]).is_equal_to([d["position"] for d in api_data_sorted]) @allure.step("Top Charts - Verify available tabs") def verify_tabs(self): for dsp in [self.SPOTIFY_TYPE, self.APPLE_TYPE, self.YOUTUBE_TYPE, self.SHAZAM_TYPE]: tab = self.wait_for_element_visible(*self.locator(self.top_charts_locators, f"{dsp}-tab")) icon = self.get_element(f"(//*[contains(@class, 'icon-{dsp}')])[last()]", "xpath") assert_that(self.is_element_displayed(element=tab)).described_as(dsp).is_true() assert_that(self.is_element_displayed(element=icon)).described_as(dsp).is_true() @allure.step("Top Charts - Verify available tabs") def verify_chosen_tab_highlighted(self, type, chosen=True): self.wait_for_table_load() tab = self.wait_for_element_visible(*self.locator(self.top_charts_locators, f"{type}-tab")) color_pink = "rgba(255, 60, 129, 1)" if chosen: color = tab.value_of_css_property("color") assert_that(color).is_equal_to(color_pink) else: color_before = tab.value_of_css_property("color") self.hover_on_element(element=tab) tab = self.wait_for_element_visible(*self.locator(self.top_charts_locators, f"{type}-tab")) color = tab.value_of_css_property("color") cursor = tab.value_of_css_property("cursor") assert_that(cursor).is_equal_to("pointer") assert_that(color).is_equal_to(color_pink) assert_that(color_before).is_not_equal_to(color) @allure.step("Top Charts - Verify Shazam tab default view") def verify_shazam_tab_default_view_and_hover(self): icon_locators = ["//*[contains(@class, 'icon-info')]", "(//*[contains(@class, 'icon-time')])[last()]"] other_el_locators = ['//*[contains(@class, "icon-calendar")]', "//*[@id='top-charts-shazam-market-dd']", "//*[@id='top-charts-shazam-city-dd']", "//*[@id='top-charts-shazam-filter-input']", "//*[@id='top-charts-shazam-export-btn']", "//*[@id='charts-table']"] tooltip_1 = """Data covers only the Shazam Daily Top 200 chart. Source: shazam.com/charts (via Chartmetric).""" shazam_latest_date = self.api_client.get_data_health_positions_shazam()[0]["latest_data_date"] shazam_latest_date = datetime.strptime(shazam_latest_date, "%Y-%m-%d").strftime(self.trackPage.get_date_format_from_locale()) tooltip_2 = f"Shazam data up to {shazam_latest_date}." for locator in icon_locators + other_el_locators: el = self.wait_for_element_visible(locator, "xpath") assert_that(self.is_element_displayed(element=el)).described_as(locator).is_true() for icon_locator, tooltip_exp in zip(icon_locators, [tooltip_1, tooltip_2]): self.hover_on_element(icon_locator, "xpath") tooltip_ui = self.get_text(self.trackPage.hint_locator, "xpath") assert_that(tooltip_ui).is_equal_to(tooltip_exp) @allure.step("Top Charts - Verify Shazam popup axes") def shazam_popup_verify_axis_and_legend(self): axes_locator = "//*[contains(@class, 'highcharts') and contains(@class, '-title')]" legend_core_locator = "top-charts-shazam-modal-window-chart-" legend_add_locators = ["legend-title", "legend-count", "0-peak-label", "0-min-label"] legend_icon_locators = ["0-peak-icon", "0-min-icon"] self.wait_for_element_visible(axes_locator, "xpath") axes_els = self.get_elements(axes_locator, "xpath") axes = [self.get_text(element=a) for a in axes_els] legend_texts = [self.get_text(f"{legend_core_locator}{l}") for l in legend_add_locators] assert_that(axes).is_equal_to(["POSITION ON CHART", "DATE"]) assert_that(legend_texts).is_equal_to(["POSITION", "ON CHART", "Peak", "Minimum"]) for l in legend_icon_locators: el = self.wait_for_element_visible(f"{legend_core_locator}{l}") assert_that(self.is_element_displayed(element=el)).is_true() @allure.step("Top Charts - get Shazam popup min max from graph") def shazam_popup_get_min_max_graph(self): graph_plot_locator = "(//*[contains(@class, 'highcharts-plot-')])[1]" position_locator = "(//*[contains(@id, 'position-popup-chart-tooltip') and contains(@id, 'value')])[last()]" values = [] e = self.wait_for_element_visible(graph_plot_locator, "xpath") height = int(e.size["height"]) width = int(e.size["width"]) + 1 self.log.info(f"height: {height}, width: {width}") param = self.trackPage.graph_get_count_days_from_calendar() step = int(width / param) self.log.info(f"step: {step}") for t in range(0, width, step): e = self.get_element(graph_plot_locator, "xpath") ActionChains(self.driver).move_to_element_with_offset(to_element=e, xoffset=t, yoffset=height).perform() tooltip = self.get_text(self.trackPage.hint_locator, "xpath") if "Position" in tooltip: position_el = self.get_element(position_locator, "xpath") position = int(self.get_text(element=position_el).split(" ")[0]) self.log.info(f"positions: {position}") values.append(position) assert_that(tooltip).contains("Position", "of") self.log.info(f"shazam positions all values: {values}") return values @allure.step("Top Charts - Shazam tab- popup verify calendar predefined periods") def graph_verify_predefined_periods(self): for p in self.trackPage.dp_predefined_periods: count_label_locator = "top-charts-shazam-modal-window-day-count-label" xaxis_before = self.trackPage.graph_get_xaxis() days_count_before = self.get_text(count_label_locator) self.trackPage.select_predefined_period(p) days_count_after = self.get_text(count_label_locator) xaxis_after = self.trackPage.graph_get_xaxis() if p == "4-weeks": dp = self.wait_for_element_visible("top-charts-shazam-modal-window-modal-window-day-picker-icon") self.click_on_element_js(element=dp) p_el_4_weeks = self.wait_for_element_visible(locator=f"//*[contains(@id, '-day-picker-{p}')]", locator_type="xpath") p_el_2_weeks = self.wait_for_element_visible(locator="//*[contains(@id, '-day-picker-2-weeks')]", locator_type="xpath") color_2 = p_el_2_weeks.value_of_css_property("background-color") color_4 = p_el_4_weeks.value_of_css_property("background-color") assert_that(color_2).is_not_equal_to(color_4) dp = self.wait_for_element_visible("top-charts-shazam-modal-window-title") self.click_on_element_js(element=dp) assert_that(days_count_before).is_equal_to(days_count_after) assert_that(xaxis_before).is_not_equal_to(xaxis_after) @allure.step("Top Charts - Shazam tab- popup verify days count hint") def popup_calendar_verify_hint(self): count_label_locator = "top-charts-shazam-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 loc = f"{weeks} weeks and {days} day" if days == 0: loc = f"{weeks} weeks" elif days > 1: loc = f"{loc}s" days_in_playlist = self.get_element("top-charts-shazam-modal-window-day-count-label") ActionChains(self.driver).move_to_element(to_element=days_in_playlist).perform() tooltip = self.is_element_displayed(locator=f"//*[text()='{loc}']", locator_type="xpath") assert_that(tooltip).described_as(loc).is_true() @allure.step("Top Charts - Shazam tab- popup verify calendar navigation") def verify_popup_calendar_navigation(self): next_month_locator = "//*[@aria-label='Next Month']" previous_month_locator = "//*[@aria-label='Previous Month']" months_locator = "//*[@class='DayPicker-Caption']" dp = self.wait_for_element_visible("top-charts-shazam-modal-window-modal-window-day-picker-icon") self.click_on_element_js(element=dp) assert_that(self.is_element_displayed(next_month_locator, "xpath")).is_false() months_before = self.get_elements(months_locator, "xpath") months_before = [self.get_text(element=m) for m in months_before] self.click_on_element_js(self.get_element(previous_month_locator, "xpath")) months_after = self.get_elements(months_locator, "xpath") months_after = [self.get_text(element=m) for m in months_after] assert_that(months_before).is_not_equal_to(months_after) assert_that(months_before[0]).is_equal_to(months_after[1]) dp = self.wait_for_element_visible("top-charts-shazam-modal-window-title") self.click_on_element_js(element=dp) assert_that(self.is_element_displayed("top-charts-shazam-modal-window-modal-window-day-picker")).is_true() @allure.step("Top Charts - Shazam tab- popup close") def shazam_close_popup(self): close_icon_locator = "top-charts-shazam-modal-window-close-icon" icon = self.wait_for_element_clickable(close_icon_locator) self.click_element(element=icon) @allure.step("Top Charts - verify no data") def verify_no_data(self): no_data_locator = "//*[text()='No data available.']" export_locator = "top-charts-shazam-export-btn" no_data_el = self.wait_for_element_visible(no_data_locator, "xpath") export_color_inactive_ui = self.get_element(export_locator).value_of_css_property("background-color") assert_that(self.is_element_displayed(element=no_data_el)).is_true() assert_that(export_color_inactive_ui).is_equal_to("rgba(242, 242, 247, 1)") @allure.step("Top Charts - verify pop-up no data") def verify_pop_up_no_data(self, verify=True): no_data_locator = "//*[text()='No data available.']" export_locator = "top-charts-shazam-modal-window-export-btn" no_data_el = self.wait_for_element_visible(no_data_locator, "xpath") export_color_inactive_ui = self.get_element(export_locator).value_of_css_property("background-color") if verify: assert_that(self.is_element_displayed(element=no_data_el)).is_true() assert_that(export_color_inactive_ui).is_equal_to("rgba(253, 253, 254, 1)") return self.is_element_displayed(element=no_data_el) @allure.step("Top Charts - Shazam tab - verify popup icon hover") def shazam_verify_popup_icon(self): icon_locator = "charts-shazam-cell-chart-position-1" color_before = self.get_element(icon_locator).value_of_css_property("background-color") self.hover_on_element(icon_locator) color_after = self.get_element(icon_locator).value_of_css_property("background-color") assert_that(color_before).is_not_equal_to(color_after) @allure.step("Top Charts - Shazam tab - verify popup elements") def shazam_popup_verify_elements(self): base_locator = "top-charts-shazam-modal-window-" els_locators = ["title", "close-icon", "track-image-cover", "track-link", "artist-link", "modal-window-day-picker", "day-count-label", "chart-chart", "chart-legend-title"] for el in els_locators: assert_that(self.is_element_displayed(f"{base_locator}{el}")).described_as(el).is_true() @allure.step("Top Charts - Shazam tab - verify popup track name") def shazam_popup_verify_track_name(self): track_name_locator = "top-charts-shazam-modal-window-track-link" tooltip_locator = "top-charts-shazam-modal-window-track-tooltip" track_el = self.wait_for_element_visible(track_name_locator) cursor = track_el.value_of_css_property("cursor") self.hover_on_element(element=track_el) tooltip_text = self.get_text(tooltip_locator) href = str(self.get_attribute_value(element=track_el, attribute="href")) assert_that(cursor).is_equal_to("pointer") assert_that(self.get_text(element=track_el)).is_equal_to(tooltip_text) assert_that(href).contains("/track/") @allure.step("Top Charts - Shazam tab - verify popup artist name") def shazam_popup_verify_artist_name(self): track_name_locator = "top-charts-shazam-modal-window-artist-link" tooltip_locator = "top-charts-shazam-modal-window-artist-tooltip" track_el = self.wait_for_element_visible(track_name_locator) cursor = track_el.value_of_css_property("cursor") self.hover_on_element(element=track_el) tooltip_text = self.get_text(tooltip_locator) url_before = self.get_url() self.click_element(element=track_el) url_after = self.get_url() assert_that(cursor).is_equal_to("auto") assert_that(self.get_text(element=track_el).replace("By ", "")).is_equal_to(tooltip_text) assert_that(url_before).is_equal_to(url_after) @allure.step("Top Charts - Shazam tab - verify popup chart") def verify_chart_indicated(self, market, city): chart_locator = "//*[contains(text(), 'Daily Top 200 ')]" chart_el = self.wait_for_element_visible(chart_locator, "xpath") chart_text = self.get_text(element=chart_el) assert_that(f"Daily Top 200 {market}, {city}").is_equal_to(chart_text) @allure.step("Top Charts - Shazam tab - verify market selector") def verify_market_selector(self, param): shazam_market_selector = "top-charts-shazam-market-dd" market_dd_filter_selector = "top-charts-shazam-market-dd-filter-input" filter_close_icon_selector = "top-charts-shazam-market-dd-filter-input-close-icon" no_markets_selector = "//*[.='No markets found.Try changing filtering parameters.']" market_item_core_selector = "//*[contains(@id, 'label')][text()='{}']" market_dd_items = "//*[contains(@id, 'label')][string-length(text()) > 0]" market_dd = self.wait_for_element_clickable(shazam_market_selector) cursor = market_dd.value_of_css_property("cursor") self.click_element(element=market_dd) color_bold = self.get_element(market_item_core_selector.format("Global"), "xpath").value_of_css_property("font-weight") color_regular = self.get_element(market_item_core_selector.format(param), "xpath").value_of_css_property("font-weight") market_dd_item_text = [self.get_text(element=e) for e in self.get_elements(market_dd_items, "xpath")] assert_that(cursor).is_equal_to("pointer") assert_that(self.is_element_displayed(market_dd_filter_selector)).is_true() assert_that(color_bold).is_not_equal_to(color_regular) assert_that(market_dd_item_text[:11]).is_equal_to(["United States", "United Kingdom", "Canada", "Mexico", "Australia", "Japan", "Spain", "France", "Germany", "South Korea", "Global"]) assert_that(market_dd_item_text[11:]).is_sorted() self.send_text(data="s", locator=market_dd_filter_selector) market_dd_item_filtered = [self.get_text(element=e).lower() for e in self.get_elements(market_dd_items, "xpath")] for item in market_dd_item_filtered: assert_that(item).contains("s") assert_that(self.is_element_displayed(filter_close_icon_selector)).is_true() self.send_text(data="sd", locator=market_dd_filter_selector) assert_that(self.is_element_displayed(no_markets_selector, "xpath")).is_true() self.click_element(filter_close_icon_selector) market_dd_item_cleared = [self.get_text(element=e) for e in self.get_elements(market_dd_items, "xpath")] assert_that(market_dd_item_text).is_equal_to(market_dd_item_cleared) self.send_text(data="Denmar", locator=market_dd_filter_selector) market_dd_item_denmark = [self.get_text(element=e) for e in self.get_elements(market_dd_items, "xpath")] assert_that(market_dd_item_denmark).contains("Denmark") self.click_element(filter_close_icon_selector) self.send_text(data="de", locator=market_dd_filter_selector) market_dd_item_de = [self.get_text(element=e) for e in self.get_elements(market_dd_items, "xpath")] assert_that(market_dd_item_de).contains("Germany") self.click_element(filter_close_icon_selector) self.send_text(data=param, locator=market_dd_filter_selector) market_dd_item_param = [self.get_text(element=e) for e in self.get_elements(market_dd_items, "xpath")] assert_that(market_dd_item_param).contains(param) self.click_element(element=market_dd) @allure.step("Top Charts - Shazam tab - verify city selector") def verify_city_selector(self, param): city_selector = "top-charts-shazam-city-dd" city_list_selector = "//*[@id='top-charts-shazam-city-dd']/..//div[string-length(text()) > 0 and not(text()='All Cities')]" city_dd = self.wait_for_element_clickable(city_selector) market_url = self.trackPage.parameter_from_url(self.market) self.click_element(element=city_dd) city_list_text = [self.get_text(element=c) for c in self.get_elements(city_list_selector, "xpath")] if param != "All Cities": city_list_text.append(param) city_list_text = sorted(city_list_text) cities_api = self.api_client.get_shazam_cities(market_url) cities_api_sorted = sorted([c["name"] for c in cities_api["items"]]) self.log.info(f"cities api: {cities_api_sorted}") assert_that(self.is_element_displayed(f"//b[text()='{param}']", "xpath")).is_true() assert_that(city_list_text).is_sorted() assert_that(cities_api_sorted).is_equal_to(city_list_text) self.click_element(element=city_dd) @allure.step("Top Charts - Shazam tab - verify columns") def shazam_verify_columns(self): columns = ["position", "trend", "name", "release-date", "peak-position", "peak-position-date", "shazams", "days-on-chart"] locator_column_header = "charts-shazam-cell-{}" for column in columns: assert_that(self.is_element_displayed(locator_column_header.format(column))).described_as(column).is_true() @allure.step("Top Charts - Shazam tab - verify track name hover and link") def shazam_verify_track_name_hover_and_link(self): track_locator = "//a[contains(@href, '/apple/track/')]" self.wait_for_element_visible(track_locator, "xpath") track_el = self.wait_for_element_clickable(track_locator, "xpath") track_ui = self.get_text(element=track_el) self.hover_on_element(element=track_el) track_tooltip = self.get_text(self.trackPage.hint_locator, "xpath") href = self.get_attribute_value(element=track_el, attribute="href") assert_that(track_ui).is_equal_to(track_tooltip) assert_that(href).contains("/apple/track/") @allure.step("Top Charts - Shazam tab - verify artist name") def shazam_verify_artist_name(self): artists_name_locator = "//*[contains(@id, 'charts-shazam-cell-name-')]//../div[string-length(text()) > 1]" self.wait_for_element_clickable(artists_name_locator, "xpath") artist_el = self.get_elements(artists_name_locator, "xpath")[0] self.hover_on_element(element=artist_el) track_tooltip = self.get_text(self.trackPage.hint_locator, "xpath") url_before = self.get_url() self.click_element(element=artist_el) url_after = self.get_url() assert_that(track_tooltip).is_equal_to("Artist and album pages are not available for the track.") assert_that(url_before).is_equal_to(url_after) @allure.step("Top Charts - click on date picker") def expand_date_picker(self): date_picker_locator = "//input[contains(@placeholder, '/')]" date_picker = self.wait_for_element_clickable(date_picker_locator, "xpath") self.click_element(element=date_picker) @allure.step("Top Charts - verify date picker") def verify_datepicker(self): weekdays_locator = "//*[@class='DayPicker-WeekdaysRow']/*" weekdays = self.get_elements(weekdays_locator, "xpath") weekdays = [self.get_text(element=w).lower() for w in weekdays] assert_that(weekdays).starts_with("mo") @allure.step("Top Charts - calendar - get month year") def get_month_year(self): month_year_locator = "//*[@class='DayPicker-Caption']" month_year = self.get_text(month_year_locator, "xpath") return month_year @allure.step("Top Charts - calendar - click forward") def calendar_click_arrow(self, arrow="next"): next_calendar_locator = f"//*[contains(@class, 'icon-{arrow}')]" self.click_element(next_calendar_locator, "xpath") def select_previous_day_verify(self): calendar_prev_month_locator = "//*[contains(@class, 'DayPicker-Day')][.='1']" self.calendar_click_arrow("prev") grid_selected_date = self.get_attribute_value(locator=calendar_prev_month_locator, locator_type="xpath", attribute="aria-label") grid_selected_date_formatted = datetime.strptime(grid_selected_date, "%a %b %d %Y").strftime(AppConfig.get("date_formats")["mm/dd/yy"]) self.click_element(calendar_prev_month_locator, "xpath") date_ui = self.get_shazam_date_ui() date_ui = datetime.strptime(date_ui, "%Y-%m-%d").strftime(AppConfig.get("date_formats")["mm/dd/yy"]) assert_that(grid_selected_date_formatted).is_equal_to(date_ui) self.expand_date_picker() color = self.get_element(calendar_prev_month_locator, "xpath").value_of_css_property("background-color") assert_that(color).is_equal_to("rgba(0, 0, 0, 1)") @allure.step("Top Charts - Verify Trending tab default view") def verify_trending_tab_default_view(self): el_locators = ['//*[contains(@class, "singlePicker")]', '(//*[@id][contains(@class, "icon-time")])[last()]', "//*[@id='top-charts-youtube-market-dd']", "//*[@id='top-charts-youtube-filter-input']", "//*[@id='top-charts-youtube-export-btn']", "//*[@id='charts-table']"] for locator in el_locators: el = self.wait_for_element_visible(locator, "xpath") assert_that(self.is_element_displayed(element=el)).described_as(locator).is_true() @allure.step("Top Charts - Verify Trending tab clock tooltip") def get_trending_tab_clock_tooltip(self, date): clock_loc = '(//*[@id][contains(@class, "icon-time")])[last()]' clock_element = self.get_element(locator=clock_loc, locator_type="xpath") ActionChains(self.driver).move_to_element(clock_element).perform() time.sleep(1) hint = self.get_element(locator=self.trackPage.hint_locator, locator_type="xpath") hint_text = self.get_text(element=hint).replace("\n", " ") self.log.info("Hint text: " + hint_text) tooltip_date = datetime.strptime(date, "%Y-%m-%d").strftime(self.trackPage.get_date_format_from_locale()) assert_that(hint_text).is_equal_to(f"Trending data up to {tooltip_date}.") @allure.step("Top Charts - verify No results message after filtering") def top_charts_verify_no_results_screen(self): no_results_part_1_loc = "//*[contains(@class, 'tableHeader')]/following-sibling::*/..//*[text()='Try another filter.']" no_results_part_2_loc = "//*[contains(@class, 'tableHeader')]/following-sibling::*/..//*[text()='No results to show.']" filter_loc = "//*[contains(@id, 'filter-input')]" export_loc = "//*[contains(@id, 'export-btn')]" no_results = self.wait_for_element_visible(locator=no_results_part_1_loc, locator_type="xpath") no_results_to_show = self.wait_for_element_visible(locator=no_results_part_2_loc, locator_type="xpath") no_results_text = self.get_text(element=no_results) filter = self.is_enabled(locator=filter_loc, locator_type="xpath") export = self.is_enabled(locator=export_loc, locator_type="xpath") no_results_to_show_text = self.get_text(element=no_results_to_show) assert_that(self.is_element_displayed(element=no_results)).is_true() assert_that(no_results_text).is_equal_to("Try another filter.") assert_that(no_results_to_show_text).is_equal_to("No results to show.") assert_that(filter).is_false() assert_that(export).is_false()