import datetime import logging import time from contextlib import suppress import allure from appium.webdriver.common.mobileby import MobileBy from appium.webdriver.common.touch_action import TouchAction from ui_automation_framework.utils import logger as cl from waiting import TimeoutExpired from app.src.helpers.api_data_provider import ApiDataProvider from app.src.helpers.waiting_wrapper import wait from app.src.pages.navigation_page import Navigation from app.src.pages.track_page import TrackPage from app.src.ui_elements.button_ui_element import ButtonUIElement from app.src.ui_elements.input_ui_element import InputUIElement from app.src.ui_elements.label_ui_element import LabelUIElement from app.src.ui_elements.list_ui_element import ListUIElement class ChartDigestPage(Navigation): log = cl.Logger(logging.DEBUG) def __init__(self, driver, api_client): super().__init__(driver) self.driver = driver self.chart_locators = self.get_page_locators("ChartPage", "chart_elements.json") self.api = api_client self.apiHelper = ApiDataProvider(self.api) # Dynamic XPATH locators not suitable for usage in Pages json object =============================================== EXITS_ENTRIES_TRACKS = '**/XCUIElementTypeOther[`name == "swipeable-list"`]/XCUIElementTypeOther/XCUIElementTypeOther' EXITS_ENTRIES_TRACK_LOCATOR = '**/XCUIElementTypeOther[`name == "swipeable-list"`]/XCUIElementTypeOther[{}]' FULL_CHARTS_TRACK_LOCATOR = '**/XCUIElementTypeOther[`name == "swipeable-list"`]/XCUIElementTypeOther[{}]' FULL_CHARTS_ALL_TRACKS_LOCATOR = '**/XCUIElementTypeOther[`name == "swipeable-list"`]/XCUIElementTypeOther' STAR_LOCATOR = "**/XCUIElementTypeOther[`name == 'swipeable-star'`][{}]" MAJOR_MOVES_STAR_LOCATOR = "**/XCUIElementTypeOther[`name == 'swipeable-list'`]/**/XCUIElementTypeOther[`name == 'swipeable-star'`][{}]" MAJOR_MOVES_TRACK_LOCATOR = '**/XCUIElementTypeOther[`name == "swipeable-list"`]/XCUIElementTypeOther/XCUIElementTypeOther[{}]' EXITS_CARD_LOCATOR = "**/XCUIElementTypeScrollView[3]/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther[{}]" ENTRIES_CARD_LOCATOR = "**/XCUIElementTypeScrollView[2]/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther[{}]" EXITS_ENTRIES_STARRED_TRACKS_LOCATOR_BY_NAME = "**/XCUIElementTypeScrollView/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther[`label CONTAINS ' ' AND label CONTAINS '{}'`]" @property def bn_chart_digest_header(self): return ButtonUIElement(self.driver, self.locator(self.chart_locators, "chart_digest_header"), "Chart digest header") @property def bn_view_charts(self): return ButtonUIElement(self.driver, self.locator(self.chart_locators, "view_charts"), "View Charts") @property def in_search(self): return InputUIElement(self.driver, self.locator(self.chart_locators, "search_field"), "Search") @property def lt_search_results(self): return ListUIElement( self.driver, (MobileBy.IOS_CLASS_CHAIN, self.FULL_CHARTS_TRACK_LOCATOR), all_elements_locator=(MobileBy.IOS_CLASS_CHAIN, self.FULL_CHARTS_ALL_TRACKS_LOCATOR), ) @property def bn_spotify_tab(self): return ButtonUIElement(self.driver, self.locator(self.chart_locators, "spotify_tab"), "spotify tab") @property def lt_star_on_major_moves(self): return ListUIElement(self.driver, (MobileBy.IOS_CLASS_CHAIN, self.MAJOR_MOVES_STAR_LOCATOR)) @property def lt_star(self): return ListUIElement(self.driver, (MobileBy.IOS_CLASS_CHAIN, self.STAR_LOCATOR)) @property def lb_starred(self): return LabelUIElement(self.driver, self.locator(self.chart_locators, "starred_label"), "Starred") @property def lb_unstarred(self): return LabelUIElement(self.driver, self.locator(self.chart_locators, "unstarred_label"), "Unstarred") @property def lt_entries_tracks(self): return ListUIElement(self.driver, (MobileBy.IOS_CLASS_CHAIN, self.ENTRIES_CARD_LOCATOR)) @property def lt_major_moves_tracks(self): return ListUIElement( self.driver, (MobileBy.IOS_CLASS_CHAIN, self.MAJOR_MOVES_TRACK_LOCATOR), all_elements_locator=(MobileBy.IOS_CLASS_CHAIN, self.locator(self.chart_locators, "major_moves_tracks")[0]), ) @property def lt_exist_entries_tracks(self): return ListUIElement( self.driver, (MobileBy.IOS_CLASS_CHAIN, self.EXITS_ENTRIES_TRACK_LOCATOR), all_elements_locator=(MobileBy.IOS_CLASS_CHAIN, self.EXITS_ENTRIES_TRACKS), ) @property def lt_exist_cards(self): return ListUIElement(self.driver, (MobileBy.IOS_CLASS_CHAIN, self.EXITS_CARD_LOCATOR)) @property def bn_show_all_entries(self): return ButtonUIElement(self.driver, self.locator(self.chart_locators, "entries_show_all"), "Show all entries") @property def lb_apple_text(self): return LabelUIElement(self.driver, self.locator(self.chart_locators, "apple_text"), "apple text") @property def bn_show_all_exits(self): return ButtonUIElement(self.driver, self.locator(self.chart_locators, "exits_show_all"), "Show all exits") @property def bn_tooltip_icon(self): return ButtonUIElement(self.driver, self.locator(self.chart_locators, "tooltip_icon"), "Tooltip icon") @property def bn_is_sony_filter(self): return ButtonUIElement(self.driver, self.locator(self.chart_locators, "charts_issony_filter"), "issony filter") @property def bn_sony_filter_option(self): return ButtonUIElement(self.driver, self.locator(self.chart_locators, "filter_sony_btn"), "Sony filter button") @property def bn_the_orchard_filter_option(self): return ButtonUIElement(self.driver, self.locator(self.chart_locators, "filter_the_orchard_btn"), "The Orchard filter button") @property def bn_awal_filter_option(self): return ButtonUIElement(self.driver, self.locator(self.chart_locators, "filter_awal_btn"), "Awal filter button") @property def bn_non_sony_filter_option(self): return ButtonUIElement(self.driver, self.locator(self.chart_locators, "filter_non_sony_btn"), "Non-Sony filter button") @property def bn_filter_done(self): return ButtonUIElement(self.driver, self.locator(self.chart_locators, "filter_done_btn"), "Filter done button") @property def bn_entries_popup(self): return ButtonUIElement(self.driver, self.locator(self.chart_locators, "entries_popup"), "Entries popup") @property def bn_exists_popup(self): return ButtonUIElement(self.driver, self.locator(self.chart_locators, "exits_popup"), "Exists popup") @property def bn_major_moves_popup(self): return ButtonUIElement(self.driver, self.locator(self.chart_locators, "major_moves_popup"), "Major moves popup") @property def bn_market_icon_entries(self): return ButtonUIElement(self.driver, self.locator(self.chart_locators, "market_icon_entries"), "ENtries market icon") @property def bn_exits_market_icon(self): return ButtonUIElement(self.driver, self.locator(self.chart_locators, "market_icon_exits"), "Exits market icon") @property def lb_market_value_full_charts(self): return LabelUIElement(self.driver, self.locator(self.chart_locators, "market_value_full_charts")) @allure.step("Clicking on the page header") def click_on_header(self): self.bn_chart_digest_header.click() return self @allure.step("Opening the full chart screen") def open_full_charts(self): self.bn_view_charts.click() return self @allure.step("Searching tracks in the full chart via the search field") def search_track_in_full_charts(self, track_name): self.in_search.send_text(track_name) self.close_keyboard_by_swipe() # TODO: should we move it to Input? return self @allure.step("Opening the track from the full chart screen") def open_track_from_full_charts(self, position): time.sleep(1) self.lt_search_results.select_by_position(position) return TrackPage(self.driver, self.api) @allure.step("Scrolling screen to major moves section") def scroll_to_major_moves(self): self.bn_spotify_tab.wait(to_assert=False) locator = "//XCUIElementTypeStaticText[@name ='Major Moves']" element = self.get_element(locator, "xpath") self.driver.execute_script("mobile: scroll", {"element": element, "toVisible": True}) return self @allure.step("Selecting DSP") def select_dsp(self, dsp_name): dsp_locator = "**/XCUIElementTypeOther[`name =='{}'`]".format(dsp_name.upper()) self.click_element(dsp_locator, "class-chain") self.lb_apple_text.wait(to_assert=False) return self @allure.step("Click to star for the track in major moves") def star_on_major_moves(self, position): self.lt_star_on_major_moves.select_by_position(position) self.lb_starred.wait(to_assert=False) return self @allure.step("Click to star for the track in exits entries charts") def star_on_exits_entries(self, position): self.lt_star.select_by_position(position) self.lb_starred.wait(to_assert=False) return self @allure.step("Click to star for the track in exits entries charts") def unstar_on_exits_entries(self, position): self.lt_star.select_by_position(position) self.lb_unstarred.wait(to_assert=False) return self @allure.step("Click to star for the track in full charts") def star_on_full_charts(self, position): self.lt_star.select_by_position(position) self.lb_starred.wait(to_assert=False) return self @allure.step("Click to star for the track in full charts") def unstar_on_full_charts(self, position): self.lt_star.select_by_position(position) self.lb_unstarred.wait(to_assert=False) return self @allure.step("Click to unstar for the track in majorm moves") def unstar_on_major_moves(self, position): self.lt_star_on_major_moves.select_by_position(position) self.lb_unstarred.wait(to_assert=False) return self @allure.step("Swiping on a track from major moves section results") def swipe_track_on_major_moves(self, position, close_keyboard=True): if close_keyboard: self.close_keyboard_by_swipe() self.lt_major_moves_tracks.get_item_by_position(position).swipe_left_long() return self @allure.step("Swiping on a track from major moves section results") def swipe_right_track_on_major_moves(self, position, close_keyboard=True): if close_keyboard: self.close_keyboard_by_swipe() self.lt_major_moves_tracks.get_item_by_position(position).swipe_right_long() return self @allure.step("Swiping on a track from exits entries sections") def swipe_track_exits_entries(self, position): self.close_keyboard_by_swipe() self.lt_exist_entries_tracks.get_item_by_position(position).swipe_left_long() return self @allure.step("Swiping right on a track from exits entries sections") def swipe_right_track_exits_entries(self, position): self.close_keyboard_by_swipe() self.lt_exist_entries_tracks.get_item_by_position(position).swipe_right_long() return self @allure.step("Swiping on a track from full charts section") def swipe_track_full_charts(self, position): self.close_keyboard_by_swipe() self.lt_search_results.get_item_by_position(position).swipe_left_long() return self @allure.step("Scrolling down on the full charts") def scroll_down_full_charts(self): self.close_keyboard_by_swipe() self.driver.execute_script("mobile: scroll", {"direction": "down"}) self.driver.execute_script("mobile: scroll", {"direction": "down"}) self.driver.execute_script("mobile: scroll", {"direction": "down"}) return self @allure.step("Clicking on entries track") def click_entries_track(self, position): self.lt_entries_tracks.select_by_position(position) return TrackPage(self.driver, self.api) @allure.step("Swiping exits cards left") def swipe_exits_cards_left(self, position): self.lt_exist_cards.get_item_by_position(position).swipe_left_long() return self @allure.step("Swiping exits cards right") def swipe_exits_cards_right(self, position): self.lt_exist_cards.get_item_by_position(position).swipe_right_long() return self @allure.step("Swiping entries cards left") def swipe_entries_cards_left(self, position): self.lt_entries_tracks.get_item_by_position(position).swipe_left_long() return self @allure.step("Swiping entries cards right") def swipe_entries_cards_right(self, position): self.lt_entries_tracks.get_item_by_position(position).swipe_right_long() return self @allure.step("Clicking on exits track") def click_exits_track(self, position): self.lt_exist_cards.select_by_position(position) return TrackPage(self.driver, self.api) @allure.step("Clicking on major moves track") def click_major_moves_track(self, position): self.scroll_to_major_moves() self.lt_star_on_major_moves.select_by_position(position, False) return TrackPage(self.driver, self.api) @allure.step("Clicking show all for entries section") def click_entries_show_all(self): self.bn_show_all_entries.click() return self @allure.step("Clicking show all for exits section") def click_exits_show_all(self): self.bn_show_all_exits.click() return self @allure.step("Clicking charts tooltip icon") def click_charts_tooltip(self): self.bn_tooltip_icon.click() time.sleep(3) return self @allure.step("Clicking on a track from full charts screen") def click_track_from_exits_entries(self, position): self.lt_exist_entries_tracks.select_by_position(position) return TrackPage(self.driver, self.api) @allure.step("Click filter selection on full charts page") def click_filter_selection(self): self.lt_search_results.get_item_by_position(1).wait(to_assert=False) self.bn_is_sony_filter.click() return self @allure.step("Selecting available filter") def select_filter(self, name): dsp_buttons = {"Sony": self.bn_sony_filter_option, "The Orchard": self.bn_the_orchard_filter_option, "Awal": self.bn_awal_filter_option, "Non-Sony": self.bn_non_sony_filter_option} initial_dsp_collection = {"Sony", "The Orchard", "Awal", "Non-Sony"} dsp_for_unchecking = initial_dsp_collection.difference(name) for dsp in dsp_for_unchecking: dsp_buttons[dsp].click() self.bn_filter_done.click() # locator = "//XCUIElementTypeOther[contains (@name, 'All Tracks') and contains(@label, 'Sony') and " "contains(@label, 'Non-Sony')]/XCUIElementTypeOther[@label='{}']".format(name) # self.wait_for_element_visible(locator, "xpath") # self.click_element(locator, "xpath") # self.bn_filter_done.click() # wait(lambda: self.bn_filter_done.is_visible() is False, exceptions=StaleElementReferenceException) # return self # filter_playlists_by_dsp(self, desired_dsp: set): # self.bn_filter.click() # initial_dsp_collection = {"Spotify", "Apple", "Amazon"} # dsp_for_unchecking = initial_dsp_collection.difference(desired_dsp) # for dsp in dsp_for_unchecking: # dsp_buttons[dsp].click() # self.bn_done_fiter_popup.click() @allure.step("Opening entries 'i' popup") def open_entries_popup(self): self.bn_entries_popup.click() return self @allure.step("Opening exits 'i' popup") def open_exits_popup(self): self.bn_exists_popup.click() return self @allure.step("Opening track in full charts") def open_track_from_full_charts_by_element(self, element): # TODO: investigate size = self.driver.get_window_size() TouchAction(self.driver).long_press(x=size["width"] / 2, y=size["height"] / 2).move_to(x=size["width"] / 2, y=size["height"] / 2 - 65).release().perform() self.driver.execute_script("mobile: scroll", {"element": element, "toVisible": True}) self.click_element(element=element) time.sleep(1) return TrackPage(self.driver, self.api) @allure.step("Opening major moves 'i' popup") def open_major_moves_popup(self): self.bn_major_moves_popup.click() return self @allure.step("Opening markets popup") def click_market_icon_entries(self): self.bn_market_icon_entries.click() return self @allure.step("Opening markets popup") def click_market_icon_exits(self): self.bn_exits_market_icon.click() return self @allure.step("Getting track title on major moves") def get_major_moves_track_title(self, position): el = self.lt_major_moves_tracks.get_item_by_position(position) el.wait(to_assert=False) raw_title = el.text.strip().partition("#")[0] title = raw_title.replace("\uE90B ", "").replace("\uE905 ", "").replace("\uE91A ", "").replace("\uE902", "").split() if title[0].isdigit(): return title[1] + " " + title[2] else: return title[0] + " " + title[1] @allure.step("Getting major moves full information") def get_major_moves_track_full_info(self, position): el = self.lt_major_moves_tracks.get_item_by_position(position) el.wait(to_assert=False) return el.text.strip() @allure.step("Getting major moves data") def get_major_moves_data(self): return [move.text for move in wait(lambda: self.lt_major_moves_tracks.elements)] @allure.step("Getting move step on major moves") def get_major_moves_move_position(self): positions = [] for move_text in self.get_major_moves_data(): raw_title = move_text.partition("#")[2] positions.append(raw_title.replace("\uE90B ", "").replace("\uE905 ", "").replace("\uE91A ", "").replace("\ue902", "").split()[0]) return positions @allure.step("Getting track title from exits") def get_exits_track_title(self, position): el = self.lt_exist_cards.get_item_by_position(position) el.wait() title = el.text.strip().replace("\uE90B ", "").replace("\uE905 ", "").replace("\uE91A ", "") self.log.info(title) return title @allure.step("Getting track title from entries") def get_entries_track_title(self, position): el = self.lt_entries_tracks.get_item_by_position(position) el.wait() raw_title = " ".join(el.text.split()[1:]) title = raw_title.replace("\uE90B ", "").replace("\uE905 ", "").replace("\uE91A ", "") self.log.info(title) return title @allure.step("Getting data from all exits/entries") def get_exits_entries_data(self): return [entry.text for entry in wait(lambda: self.lt_exist_entries_tracks.elements)] @allure.step("Getting track name on full charts entries") def get_full_enrties_track_title(self, position): el = self.lt_exist_entries_tracks.get_item_by_position(position) el.wait() raw_title = el.text.strip().partition(" #")[0] title = raw_title.replace("\uE90B ", "").replace("\uE905 ", "").replace("\uE91A ", "").replace("\uE91A ", "")[:11] self.log.info(title) return title @allure.step("Getting track name on full charts exits") def get_full_exits_track_title(self, position): el = self.lt_exist_entries_tracks.get_item_by_position(position) el.wait() raw_title = el.text.strip() title = raw_title.replace("\uE90B ", "").replace("\uE905 ", "").replace("\uE91A ", "").replace("\uE91A ", "")[:11] self.log.info(title) return title @allure.step("Getting tracks postions in exits/entries") def get_entries_positions_for_not_starred_tracks(self): elements = self.get_elements(*self.locator(self.chart_locators, "exits_entries_tracks_not_starred")) positions = [int(self.get_attribute_value(element=elem, attribute="label").partition(" #")[2].replace(" \ue90b", "")) for elem in elements] self.log.info(positions) return positions @allure.step("Getting track name on full charts exits") def get_full_charts_track_title(self, position): el = self.lt_search_results.get_item_by_position(position) el.wait(to_assert=False) raw_title = el.text.strip().partition(" #")[0] title = raw_title.replace("\uE90B ", "").replace("\uE905 ", "").replace("\uE91A ", "").replace("\uE91A ", "").replace("\ue902", "").replace("", "").split() self.log.info(title) if title[0].isdigit(): return title[1] + " " + title[2] else: return title[0] + " " + title[1] @allure.step("Getting track name on full charts exits") def get_full_charts_track_title_with_icons(self, position): el = self.lt_search_results.get_item_by_position(position) el.wait() raw_title = el.text.strip().partition(" #")[0] return raw_title @allure.step("Getting info on full charts") def get_full_charts_track_info(self, position): el = self.lt_search_results.get_item_by_position(position) el.wait() return el.text @allure.step("Getting track name on full charts exits") def get_full_charts_track_title_without_formatting(self, position): el = self.lt_search_results.get_item_by_position(position) el.wait() raw_title = el.text.strip() title = raw_title.replace("\uE90B ", "").replace("\uE905 ", "").replace("\uE91A ", "").replace("\uE91A ", "").replace("\ue902", "").replace("\ue90b", "").replace("", "").partition(" #")[0].split() if title[0].isdigit(): return title[1] + " " + title[2] else: return title[0] + " " + title[1] @allure.step("Getting search results") def get_full_charts_search_results(self): tracks = [] self.wait_for_element_visible(self.FULL_CHARTS_ALL_TRACKS_LOCATOR, "class-chain") search_elements = self.get_elements(self.FULL_CHARTS_ALL_TRACKS_LOCATOR, "class-chain") for element in search_elements: tracks.append(self.get_attribute_value(None, None, element, "label")) return tracks @allure.step("Getting full charts tracks") def get_full_charts_tracks(self): self.wait_for_element_visible(self.FULL_CHARTS_ALL_TRACKS_LOCATOR, "class-chain") return self.get_elements(self.FULL_CHARTS_ALL_TRACKS_LOCATOR, "class-chain") @allure.step("Getting full charts data") def get_full_charts_data(self): charts = self.get_full_charts_tracks() data = [self.get_text(element=chart) for chart in charts] return data @allure.step("Getting market value from popup") def get_market_exits_entries(self): time.sleep(1) self.wait_for_element_visible(*self.locator(self.chart_locators, "market_value_exits_entries")) value = self.get_attribute_value(*self.locator(self.chart_locators, "market_value_exits_entries"), None, "label") return value @allure.step("Getting market value from popup") def get_market_full_charts(self): self.lb_market_value_full_charts.wait(to_assert=False) with suppress(TimeoutExpired): return wait(lambda: self.lb_market_value_full_charts.label, timeout=2) @allure.step("Getting tracks quantity from entries Show All button") def get_entries_show_all_quantitiy(self): return int(self.bn_show_all_entries.label.split()[2].strip("()")) @allure.step("Getting tracks quantity from exits Show All button") def get_exits_show_all_quantitiy(self): return int(self.bn_show_all_exits.label.split()[2].strip("()")) @allure.step("Getting tracks quantity on opened exits/entries tabs") def get_exits_entries_tracks_count(self): return len(self.lt_exist_entries_tracks.elements) @allure.step("Verifying full charts page is opened") def is_full_charts_opened(self): return self.in_search.is_visible() @allure.step("Verifying info popup is opened") def is_entries_popup_opened(self): return self.is_element_displayed(*self.locator(self.chart_locators, "entries_popup_text")) @allure.step("Verifying info popup is opened") def is_exits_popup_opened(self): return self.is_element_displayed(*self.locator(self.chart_locators, "exits_popup_text")) @allure.step("Verifying info popup is opened") def is_major_moves_popup_opened(self): return self.is_element_displayed(*self.locator(self.chart_locators, "major_moves_popup_text")) @allure.step("Verifying DSP section") def is_dsp_section_displayed(self): return self.bn_spotify_tab.is_visible() and self.is_element_displayed(*self.locator(self.chart_locators, "apple_tab")) @allure.step("Verifying exits section") def is_exits_section_displayed(self): return self.is_element_present(*self.locator(self.chart_locators, "exits")) @allure.step("Verifying major moves section") def is_major_moves_section_displayed(self): self.scroll_to_major_moves() return self.is_element_present(*self.locator(self.chart_locators, "major_moves")) @allure.step("Verifying entries section") def is_entries_section_displayed(self): self.scroll_up() self.wait_for_element_visible(*self.locator(self.chart_locators, "entries")) return self.is_element_present(*self.locator(self.chart_locators, "entries")) @allure.step("Verifying that only sony tracks are available") def are_sony_only_tracks_shown(self): self.wait_for_element_visible(*self.locator(self.chart_locators, "sony_tracks")) if not self.is_element_displayed(*self.locator(self.chart_locators, "non_sony_tracks")): return True @allure.step("Verifying that only non sony tracks are available") def are_non_sony_only_tracks_shown(self): self.wait_for_element_visible(*self.locator(self.chart_locators, "non_sony_tracks")) if not self.is_element_displayed(*self.locator(self.chart_locators, "sony_tracks")): return True @allure.step("Verifying that all tracks are available") def are_all_tracks_shown(self): return self.is_element_displayed(*self.locator(self.chart_locators, "sony_tracks")) and self.is_element_displayed(*self.locator(self.chart_locators, "non_sony_tracks")) @allure.step("Verifying the track is starred on the full charts") def is_track_starred(self, track_name): track_locator = self.EXITS_ENTRIES_STARRED_TRACKS_LOCATOR_BY_NAME.format(track_name[:10]) self.wait_for_element_visible(track_locator, "class-chain") return self.is_element_displayed(track_locator, "class-chain") @allure.step("Verifying the track is starred on the full charts") def is_track_unstarred(self, track_name): track_locator = self.EXITS_ENTRIES_STARRED_TRACKS_LOCATOR_BY_NAME.format(track_name[:10]) return not self.is_element_displayed(track_locator, "class-chain") @allure.step("Verifying no search results state is displayed") def are_no_search_results_displayed(self): return self.is_element_displayed(*self.locator(self.chart_locators, "no_search_results")) @allure.step("Verifying no spotify charts data message is displayed") def is_full_charts_no_spotify_data_message_displayed(self): return self.is_element_displayed(*self.locator(self.chart_locators, "no_spotify_charts_data_msg")) @allure.step("Verifying no apple charts data message is displayed") def is_full_charts_no_apple_data_message_displayed(self): return self.is_element_displayed(*self.locator(self.chart_locators, "no_apple_charts_data_msg")) @allure.step("Verifying proper tooltip message shown for available apple market data") def is_full_charts_apple_available_market_data_tooltip_msg_displayed(self, country_code): current_date = self.__get_current_date_in_tooltip_format("apple", country_code).split() date_locator = "//XCUIElementTypeStaticText[contains(@name, '{}') and contains(@name, '{}')]".format(current_date[0] + " " + current_date[1], current_date[3]) return self.is_element_displayed(*self.locator(self.chart_locators, "tooltip_apple_available_text")) and self.is_element_displayed(date_locator, "xpath") @allure.step("Verifying proper tooltip message shown for available spotify market data") def is_full_charts_spotify_available_market_data_tooltip_msg_displayed(self, country_code): current_date = self.__get_current_date_in_tooltip_format("spotify", country_code).split() date_locator = "//XCUIElementTypeStaticText[contains(@name, '{}') and contains(@name, '{}')]".format(current_date[0] + " " + current_date[1], current_date[3]) return self.is_element_displayed(*self.locator(self.chart_locators, "tooltip_spotify_available_text")) and self.is_element_displayed(date_locator, "xpath") @allure.step("Verifying proprt tooltip message shown for unavailable apple market data") def is_full_charts_unavailable_market_data_tooltip_msg_displayed(self): return self.is_element_displayed(*self.locator(self.chart_locators, "tooltip_unavailable_text")) @allure.step("Verifying exits cards are swiped") def is_exits_card_swiped_left(self, position): return self.lt_exist_cards.get_item_by_position(position + 1).is_visible() @allure.step("Verifying exits cards are swiped") def is_exits_card_swiped_right(self, position): return self.lt_exist_cards.get_item_by_position(position - 1).is_visible() @allure.step("Verifying entries cards are swiped") def is_entries_card_swiped_left(self, position): new_position = position + 1 return self.lt_entries_tracks.get_item_by_position(new_position).is_visible() @allure.step("Verifying minimum position step change in major moves") def is_major_moves_minimum_step(self, step, positions_list): if any(int(i) < step for i in positions_list): return False else: return True @allure.step("Verifying entries cards are swiped") def is_entries_card_swiped_right(self, position): new_position = position - 1 return self.lt_entries_tracks.get_item_by_position(new_position).is_visible() @allure.step("Verifying 'view charts' button is displayed") def is_view_charts_displayed(self): return self.bn_view_charts.is_visible() @allure.step("Verifying star icon is displayed for track") def is_major_moves_star_icon_displayed(self, position): return self.lt_star.get_item_by_position(position).is_visible() @allure.step("Verifying star icon is closed for track") def is_major_moves_star_icon_closed(self, position): return not self.lt_star.get_item_by_position(position).is_visible() @allure.step("Verifiying star icon is displayed for exits/entries track") def is_entries_exits_star_icon_displayed(self, position): return self.lt_star.get_item_by_position(position).is_visible() @allure.step("Verifiying star icon is closed for exits/entries track") def is_entries_exits_star_icon_closed(self, position): return not self.lt_star.get_item_by_position(position).is_visible() @allure.step("Verifying charts not available state for spotify dsp") def is_spotify_chart_not_available_shown(self): return self.is_element_displayed(*self.locator(self.chart_locators, "no_spotify_charts_data_msg")) @allure.step("Verifying charts not available state for apple dsp") def is_apple_chart_not_available_shown(self): return self.is_element_displayed(*self.locator(self.chart_locators, "no_apple_charts_data_msg")) @allure.step("Verifying starred entries track is shown on the first position") def is_entries_starred_track_is_displayed_on_first_position(self, track_name): first_track_label = self.get_attribute_value(*self.locator(self.chart_locators, "entries_first_track"), None, "label") return "" in first_track_label and track_name in first_track_label @allure.step("Verifying starred exits track is shown on the first position") def is_exits_starred_track_is_displayed_on_first_position(self, track_name): first_track_label = self.get_attribute_value(*self.locator(self.chart_locators, "exites_first_track"), None, "label") return "" in first_track_label and track_name in first_track_label def is_search_value_in_list(self, value, results): passed = True value_formatted = value.replace("’", "'").replace("", "").replace("", "").lower() for element in results: element_formatted = str(element).replace("’", "'").lower() if value_formatted not in element_formatted: self.log.info("Passed search string: " + value_formatted + " result title: " + element_formatted) passed = False else: continue return passed def __get_current_date_in_tooltip_format(self, dsp, country): if dsp == "spotify": chart_date_spotify = self.apiHelper.get_top_charts_date("{}".format(dsp), "{}".format(country), "position", 200) today = datetime.datetime.strptime(chart_date_spotify, "%Y-%m-%d").strftime("%A, %B %d, %Y") elif dsp == "apple": chart_date_apple = self.apiHelper.get_top_charts_date("{}".format(dsp), "{}".format(country), "position", 200) today = datetime.datetime.strptime(chart_date_apple, "%Y-%m-%d").strftime("%A, %B %d, %Y") return today @allure.step("Verifying that header contains vendors that we have in filters") def is_header_contains_vendors(self, vendors: list): vendors = ", ".join(vendors) locator = f"**/XCUIElementTypeOther[`label == \"Charts  {vendors}\"`][2]" return self.is_element_displayed(locator, "class-chain")