import logging import time 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 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 PlaylistPage(Navigation): log = cl.Logger(logging.DEBUG) MARKET_LOCATOR_BY_NAME = '**/XCUIElementTypeOther[`name == "toggle-styled" AND label CONTAINS "{}"`]' TRACK_CARD_LOCATOR = "**/XCUIElementTypeOther[`name == 'swipeable-list'`]/XCUIElementTypeOther[`label BEGINSWITH '' OR label BEGINSWITH '' AND label CONTAINS 'Added'`][{}]" STAR_LOCATOR = '**/XCUIElementTypeOther[`name == "swipeable-star"`][{}]' def __init__(self, driver, api_client): super().__init__(driver) self.api = api_client self.driver = driver self.playlist_locators = self.get_page_locators("PlaylistPage", "playlist_elements.json") @property def bn_date_range(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "date_range_selector"), "Date range selector") @property def bn_markets(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "markets_btn"), "Markets") @property def bn_markets_done(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "markets_done_btn"), "Markets Done") @property def bn_markets_cancel(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "markets_cancel_btn"), "Markets Cancel") @property def in_markets_search(self): return InputUIElement(self.driver, self.locator(self.playlist_locators, "markets_search_field"), "Markets search") @property def lt_markets(self): return ListUIElement(self.driver, by_text_locator=(MobileBy.IOS_CLASS_CHAIN, self.MARKET_LOCATOR_BY_NAME)) @property def bn_playlist_popup(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "playlist_popup"), "Playlist popup") @property def bn_star(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "star_button"), "Star button") @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.playlist_locators, "starred_label"), "Starred") @property def lb_unstarred_playlist(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "unstarred_playlist_label"), "Unstarred playlist label") @property def lb_unstarred_track(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "unstarred_track_label"), "Unstarred") @property def in_search(self): return InputUIElement(self.driver, self.locator(self.playlist_locators, "search_text_area"), "Search") @property def bn_streams_detailed(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "streams_detailed_button"), "Streams detailed") @property def bn_listeners_detailed(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "listeners_detailed_button"), "Listeners detailed") @property def bn_followers_detailed(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "followers_detailed_button"), "Followers detailed") @property def bn_clear_search(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "clear_search_icon"), "Clear search") @property def bn_cancel(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "cancel_button"), "Cancel") @property def lb_percent_of_global(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "percent_of_global_value"), "Percent of global") @property def lt_track_cards(self): return ListUIElement(self.driver, (MobileBy.IOS_CLASS_CHAIN, self.TRACK_CARD_LOCATOR)) @property def bn_close_streams_graph(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "close_streams_graph"), "Close streams graph") @property def bn_sorting_popup_done(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "sorting_popup_done_button"), "Sorting popup done ") @property def bn_personalized_playlist_i_icon(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "personalized_playlist_i_icon"), "personalised i icon") @property def bn_date_picker_4_weeks(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "date_picker_4_weeks"), "Date picker 2 weeks") @property def bn_date_picker_done(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "date_picker_done"), "Date picker done") @property def bn_date_picker_8_weeks(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "date_picker_8_weeks"), "Date picker 8 weeks") @property def bn_date_picker_12_weeks(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "date_picker_12_weeks"), "Date picker 12 weeks") @property def bn_date_picker_26_weeks(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "date_picker_26_weeks"), "Date picker 26 weeks") @property def bn_date_picker_2_weeks(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "date_picker_2_weeks"), "Date picker 2 weeks") @property def lb_streams_performance_card(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "streams_performance_card"), "Stream performance card") @property def lb_followers_performance_card(self): return LabelUIElement( self.driver, self.locator(self.playlist_locators, "followers_performance_card"), "Followers performance card", ) @property def lb_streams_detailed_card_data_spotify(self): return LabelUIElement( self.driver, self.locator(self.playlist_locators, "streams_detailed_card_data_spotify"), "Streams detailed card data spotify", ) @property def lb_streams_detailed_card_data_apple(self): return LabelUIElement( self.driver, self.locator(self.playlist_locators, "streams_detailed_card_data_apple"), "streams detailed card data apple", ) @property def lb_listeners_detailed_card_data(self): return LabelUIElement( self.driver, self.locator(self.playlist_locators, "listeners_detailed_card_data"), "listeners detailed card data", ) @property def lb_followers_detailed_card_data(self): return LabelUIElement( self.driver, self.locator(self.playlist_locators, "followers_detailed_card_data"), "followers detailed card data", ) @property def lb_listeners_performance_card(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "listeners_performance_card")) @property def lb_tracklist_frontline_card(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "tracklist_frontline_card"), "tracklist frontline card") @property def lb_tracklist_sony_card(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "tracklist_sony_card"), "tracklist sony card") @property def lb_tracklist_local_card(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "tracklist_local_card"), "tracklist local card") @property def lb_streams_detailed_graph_title(self): return LabelUIElement( self.driver, self.locator(self.playlist_locators, "streams_detailed_graph_title"), "streams detailed graph title", ) @property def lb_followers_detailed_graph_title(self): return LabelUIElement( self.driver, self.locator(self.playlist_locators, "followers_detailed_graph_title"), "followers detailed graph title", ) @property def lb_listeners_detailed_graph_title(self): return LabelUIElement( self.driver, self.locator(self.playlist_locators, "listeners_detailed_graph_title"), "listeners detailed graph title", ) @property def lb_title(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "title"), "Title") @property def lb_image(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "image"), "Title") @property def lb_name(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "name"), "Name") @property def lb_is_personalized(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "is_personalized_lbl"), "Is personalized") @property def lb_updated_date(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "updated_date"), "Updated date") @property def lb_vendor_link(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "vendor_link"), "Vendor link") @property def lb_scrolled_header(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "scrolled_header"), "Scrolled header") @property def lb_personalized_playlist_i_title(self): return LabelUIElement( self.driver, self.locator(self.playlist_locators, "personalized_playlist_i_title"), "Personalised playlist i title", ) @property def lb_personalized_playlist_i_content(self): return LabelUIElement( self.driver, self.locator( self.playlist_locators, "personalized_playlist_i_content", ), "Personalised playlist i content", ) @property def lb_performance_no_followers_message(self): return LabelUIElement( self.driver, self.locator(self.playlist_locators, "performance_no_followers_message"), "Performance no followers msg", ) @property def lb_performance_no_listeners_message(self): return LabelUIElement( self.driver, self.locator(self.playlist_locators, "performance_no_listeners_message"), "Performance no listeners msg", ) @property def lb_performance_no_streams_message(self): return LabelUIElement( self.driver, self.locator(self.playlist_locators, "performance_no_streams_message"), "Performance no streams msg", ) @property def lb_date_picker_title(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "date_picker_title"), "Date picker title") @property def lb_playlist_popup_text(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "playlist_popup_text"), "playlist popup text") @property def lb_playlist_popup_text_full(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "playlist_popup_text_full"), "playlist popup text full") @property def lt_playlist_tracks(self): return ListUIElement( self.driver, all_elements_locator=(MobileBy.IOS_CLASS_CHAIN, self.locator(self.playlist_locators, "playlist_tracks")[0]), ) @property def lb_line_value(self): return LabelUIElement(self.driver, self.locator(self.playlist_locators, "line_value")) @property def bn_account_name_owner_static_text(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "account_name_owner_static_text")) @property def bn_account_name_owner_pill_btn(self): return ButtonUIElement(self.driver, self.locator(self.playlist_locators, "account_name_owner_pill_button")) @allure.step("Swiping playlist header") def swipe_header_left(self, vendor): if vendor == "Spotify": self.bn_account_name_owner_static_text.swipe_left_long() else: self.bn_account_name_owner_pill_btn.swipe_left_long() @allure.step("Opening date range selector") def open_date_picker(self): self.bn_date_range.click() return self @allure.step("Opening markets selection screen in profile settings") def open_markets(self): self.bn_markets.click() return self @allure.step("Selecting market via the search field") def select_market_via_search(self, query): self.bn_markets_done.wait(to_assert=False) self.in_search.send_text(query) self.lt_markets.select_by_text(query) self.bn_markets_done.click() return self @allure.step("Opening playlists 'i' popup") def open_playlists_popup(self): self.bn_playlist_popup.click() return self @allure.step("Swiping track in a track list left") def swipe_track_in_tracklist(self, position): self.lt_track_cards.get_item_by_position(position).swipe_left_long() return self @allure.step("Starring playlist on the playlist page") def star_playlist(self): self.bn_star.click() self.lb_starred.wait(to_assert=False) return self @allure.step("Unstarring playlist on the playlist page") def unstar_playlist(self): self.bn_star.click() self.lb_unstarred_playlist.wait(to_assert=False) return self @allure.step("Starring track in a track list") def star_track(self, position): self.lt_star.select_by_position(position) self.lb_starred.wait(to_assert=False) return self @allure.step("Unstarring track in a track list") def unstar_track(self, position): self.lt_star.select_by_position(position) self.lb_unstarred_track.wait(to_assert=False) return self @allure.step("Searching for track in playlists") def search_for_track_in_playlists(self, query): self.in_search.send_text(query) self.close_keyboard_by_swipe() return self @allure.step("Selecting sorting") def select_sorting_by(self, sort_by): locator = '**/XCUIElementTypeOther[`label BEGINSWITH "{}"`][-1]'.format(sort_by) self.wait_for_element_clickable(locator, "class-chain") self.click_element(locator, "class-chain") self.bn_sorting_popup_done.click() return self @allure.step("Click detailed button for streams graphs") def click_streams_detailed_button(self): self.bn_streams_detailed.click() return self @allure.step("Click detailed button for listeners graphs") def click_listeners_detailed_button(self): self.bn_listeners_detailed.click() return self @allure.step("Click detailed button for followers graphs") def click_followers_detailed_button(self): self.bn_followers_detailed.click() return self @allure.step("Clicking 'x' to clear search field") def clear_playlists_search_field(self): self.bn_clear_search.click() self.close_keyboard_by_swipe() return self @allure.step("Clicking cancel button on playlists search screen") def click_playlists_search_cancel_button(self): self.bn_cancel.click() return self @allure.step("Clicking i icon for personalized playlist") def click_personalized_playlist_i_icon(self): self.bn_personalized_playlist_i_icon.click() return self @allure.step("Clicking on a search field") def click_search_field(self): # TODO: is it the same as search ? self.wait_for_element_visible(*self.locator(self.playlist_locators, "search_field")) self.click_element(*self.locator(self.playlist_locators, "search_field")) return self @allure.step("Clicking on a track card") def click_track_card(self, position): self.lt_track_cards.select_by_position(position, False) return TrackPage(self.driver, self.api) @allure.step("Clicking sorting icon") def click_sorting_icon(self): time.sleep(4) element = self.wait_for_element_present(*self.locator(self.playlist_locators, "sorting_icon")) self.click_element(element=element) return self @allure.step("Clicking on track card for sony track") def click_track_card_for_sony_track(self, position): is_found = False locator = '**/XCUIElementTypeOther[`label BEGINSWITH "SONY" AND label CONTAINS "Added"`]' self.scroll_down_to_tracks() element = None while not is_found: try: element = self.get_elements(locator, "class-chain")[position] is_found = True except IndexError: self.scroll_down().scroll_down().scroll_down() element = self.get_elements(locator, "class-chain")[position] self.driver.execute_script("mobile: scroll", {"element": element, "toVisible": True}) self.click_element(element=element) return TrackPage(self.driver, self.api) @allure.step("Clicking on performance detailed graph") def click_performance_detailed_graph(self): size = self.driver.get_window_size() actions = TouchAction(self.driver) actions.press(x=size["width"] / 6, y=size["height"] / 1.8).wait(4000) actions.perform() return self @allure.step("Clicking on listeners detailed graph") def click_listeners_detailed_graph(self): size = self.driver.get_window_size() actions = TouchAction(self.driver) actions.press(x=size["width"] / 4, y=size["height"] / 1.8).wait(4000).perform() return self @allure.step("Closing graph detailed view") def close_graph_detailed_view(self): self.bn_close_streams_graph.click() return self @allure.step("Scrolling search results") def scroll_playlists_search_results(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("Scroll to see stickable header") def scroll_down_to_tracks(self): size = self.driver.get_window_size() action = TouchAction(self.driver) action.long_press(x=size["width"] / 2, y=size["height"] * 0.65).move_to(x=size["width"] / 2, y=size["height"] * 0.2).release().perform() return self @allure.step("Selecting 4 weeks date range") def select_4_weeks_date_filter(self): self.bn_date_picker_4_weeks.click() self.bn_date_picker_done.click() return self @allure.step("Selecting 8 weeks date range") def select_8_weeks_date_filter(self): self.bn_date_picker_8_weeks.click() self.bn_date_picker_done.click() return self @allure.step("Selecting 12 weeks date range") def select_12_weeks_date_filter(self): self.bn_date_picker_12_weeks.click() self.bn_date_picker_done.click() return self @allure.step("Selecting 26 weeks date range") def select_26_weeks_date_filter(self): self.bn_date_picker_26_weeks.click() self.bn_date_picker_done.click() return self @allure.step("Selecting 2 weeks date range") def select_2_weeks_date_filter_without_click(self): self.bn_date_picker_2_weeks.click() return self @allure.step("Selecting 2 weeks date range") def select_4_weeks_date_filter_without_click(self): self.bn_date_picker_4_weeks.click() return self @allure.step("Selecting specified market") def select_market(self, market): self.click_on_market_in_markets_list(market) self.click_markets_done() return self @allure.step("Clicking on market from the list") def click_on_market_in_markets_list(self, market): # locator = "//XCUIElementTypeOther[@label='" + market + "']" locator = f'**/XCUIElementTypeOther[`name == "toggle-styled" AND label == "{market}"`]' self.wait_for_element_visible(locator, "class-chain") element = self.get_element(locator, "class-chain") self.driver.execute_script("mobile: scroll", {"element": element, "toVisible": True}) self.wait_for_element_visible(locator, "class-chain") self.click_element(locator, "class-chain") return self @allure.step("Clicking Done button on markets list") def click_markets_done(self): self.bn_markets_done.click() return self def click_markets_cancel(self): self.bn_markets_cancel.click() return self @allure.step("Getting daily value on detailed graph") def get_daily_value_from_detailed_view(self): self.lb_line_value.wait(to_assert=False) return self.lb_line_value.text @allure.step("Getting playlists search results") def get_playlists_search_results(self): search_results = '//XCUIElementTypeOther[@name="swipeable-star"]/' '../../../../XCUIElementTypeOther[contains(@label, "Added")]' self.wait_for_element_visible(search_results, "xpath") search_elements = self.get_elements(search_results, "xpath") tracks = [self.get_attribute_value(None, None, element, "label") for element in search_elements] self.log.info(tracks) return tracks @allure.step("Getting name from the track card") def get_track_name(self, position): track_info = self.lt_track_cards.get_item_by_position(position).text.split() if track_info[1] == "SONY": return track_info[2] + " " + track_info[3] else: return track_info[1] + " " + track_info[2] @allure.step("Getting 'added days' and 'positions' values from tracks cards") def get_playlist_tracks_added_dates_and_positions(self): tracks = wait(lambda: self.lt_playlist_tracks.elements) dates = [] track_positions_for_secondary_sorting_in_case_dates_not_available = [] for track in tracks: track_info = track.text.partition("#")[2] if "Added" in track_info and "Year" not in track_info: days_added_value = track.text.partition("Added")[2].split()[0] if days_added_value != "Today": dates.append(int(days_added_value)) elif "Added" in track_info and "Year" in track_info: days_added_value = track.text.partition("Added")[2].split()[0] if days_added_value != "Today": dates.append(int(days_added_value) * 365) if track_info.split()[2] == "N/A": track_positions_for_secondary_sorting_in_case_dates_not_available.append(int(track.text.partition("#")[2].split()[0])) return dates, track_positions_for_secondary_sorting_in_case_dates_not_available @allure.step("Getting position values from tracks cards") def get_playlist_tracks_positions(self): return [int(track.text.partition("#")[2].split()[0]) for track in wait(lambda: self.lt_playlist_tracks.elements)] @allure.step("Getting data from playlist performance streams card") def get_streams_performance_card_data(self): return self.lb_streams_performance_card.visible_text @allure.step("Getting data from playlist performance followers card") def get_followers_performance_card_data(self): return self.lb_followers_performance_card.visible_text @allure.step("Getting percent of total value on detailed market") def get_percent_of_total_value(self): return self.lb_percent_of_global.text @allure.step("Getting dates from playlist performance streams card") def get_streams_performance_card_data_dates(self): data = self.get_streams_performance_card_data().split() if data[0] == "Streams": return data[2], data[3] return data[3], data[4] @allure.step("Getting dates from playlist performance streams card") def get_listeners_performance_card_data_dates(self): data = self.get_listeners_performance_card_data().split() return data[2], data[3] @allure.step("Getting dates from playlist performance followers card") def get_followers_performance_card_data_dates(self): data = self.get_followers_performance_card_data().split() return data[5], data[6] @allure.step("Getting dates from playlist performance streams detailed card") def get_spotify_streams_performance_card_detailed_data(self): return self.lb_streams_detailed_card_data_spotify.visible_text @allure.step("Getting dates from playlist performance streams detailed card") def get_apple_streams_performance_card_detailed_data(self): return self.lb_streams_detailed_card_data_apple.visible_text @allure.step("Getting dates from playlist performance listeners detailed card") def get_listeners_performance_card_detailed_data(self): return self.lb_listeners_detailed_card_data.visible_text @allure.step("Getting dates from playlist performance followers detailed card") def get_followers_performance_card_detailed_data(self): return self.lb_followers_detailed_card_data.visible_text @allure.step("Getting data from playlist performance listeners card") def get_listeners_performance_card_data(self): return self.lb_listeners_performance_card.visible_text @allure.step("Getting tracklist frontline data") def get_tracklist_frontline_data(self): return self.lb_tracklist_frontline_card.visible_text @allure.step("Getting tracklist sony data") def get_tracklist_sony_data(self): return self.lb_tracklist_sony_card.visible_text @allure.step("Getting tracklist local data") def get_tracklist_local_data(self): return self.lb_tracklist_local_card.visible_text @allure.step("Verifying streams detailed graphs is opened") def is_streams_detailed_graphs_opened(self): self.lb_streams_detailed_graph_title.wait(to_assert=False) orientation = self.driver.orientation return orientation == "LANDSCAPE" and self.lb_streams_detailed_graph_title.is_visible() @allure.step("Verifying followers detailed graphs is opened") def is_followers_detailed_graphs_opened(self): orientation = self.driver.orientation return orientation == "LANDSCAPE" and self.lb_followers_detailed_graph_title.is_visible() @allure.step("Verifying streams detailed graphs is opened") def is_listeners_detailed_graphs_opened(self): self.lb_listeners_detailed_graph_title.wait(to_assert=False) orientation = self.driver.orientation return orientation == "LANDSCAPE" and self.lb_listeners_detailed_graph_title.is_visible() @allure.step("Verifying playlist page is opened by name") def is_playlist_page_opened_for_name(self, playlist_name): playlist_name_locator = '**/XCUIElementTypeStaticText[`label CONTAINS "{}"`]'.format(playlist_name) return self.is_element_present(playlist_name_locator, "class-chain") and self.is_element_present(*self.locator(self.playlist_locators, "title")) @allure.step("Verifying spotify playlist header content") def is_personalized_playlist_page_header_displayed_first_slide(self): return self.lb_image.is_present() and self.lb_name.is_present() and self.lb_is_personalized.is_present() and self.bn_account_name_owner_static_text.is_present() @allure.step("Verifying spotify playlist header content") def is_personalized_playlist_page_header_displayed_second_slide(self): return self.lb_updated_date.is_visible() and self.is_element_displayed(*self.locator(self.playlist_locators, "vendor_link")) @allure.step("Verifying spotify playlist header content") def is_apple_playlist_page_header_displayed_first_slide(self): return self.lb_title.is_present() and self.lb_image.is_present() and self.lb_name.is_present() and not self.lb_is_personalized.is_present() and self.bn_account_name_owner_pill_btn.is_present() @allure.step("Verifying spotify playlist header content") def is_apple_playlist_page_header_displayed_second_slide(self): return self.lb_updated_date.is_visible() and self.lb_vendor_link.is_visible() @allure.step("Verifying search screen is opened") def is_playlists_search_screen_displayed(self): return self.bn_cancel.is_visible() @allure.step("Verifying sorting popup presence") def is_sorting_popup_opened(self): self.bn_sorting_popup_done.wait(to_assert=False) return self.bn_sorting_popup_done.is_visible() @allure.step("Verifying sorting title represents current sorting") def is_selected_sorting_title_displayed(self, sorting_type): locator = '**/XCUIElementTypeStaticText[`label == "{}"`]'.format(sorting_type) return self.is_element_present(locator, "class-chain") @allure.step("Verifying scrolled header contains data from the main track") def is_scrolled_header_contains(self, main_track_data): return main_track_data in self.lb_scrolled_header.text @allure.step("Verifying personalized playlist info popup presence") def is_personalized_playlist_info_popup_shown(self): return self.lb_personalized_playlist_i_title.is_visible() and self.lb_personalized_playlist_i_content.is_visible() @allure.step("Verifying playlists placements page is opened") def is_playlists_placements_page_opened(self): return self.lb_title.is_visible() @allure.step("Verifying playlists placements page is opened by name") def is_playlists_placements_page_opened_for_name(self, playlist_name): palylist_name_locator = '**/XCUIElementTypeStaticText[`label CONTAINS "{}"`]'.format(playlist_name) return self.is_element_displayed(palylist_name_locator, "class-chain") and self.lb_title.is_visible() @allure.step("Verifying initiated search screen is displayed") def is_initiated_search_displayed(self, query): locator = f'//XCUIElementTypeTextField[@value="{query}"]' return self.is_element_displayed(locator, "xpath") @allure.step("Verifying performance followers no data message") def is_no_performance_followers_message_shown(self): return wait(self.lb_performance_no_followers_message.is_present) @allure.step("Verifying performance listeners no data message") def is_no_performance_listeners_message_shown(self): return wait(self.lb_performance_no_listeners_message.is_present) @allure.step("Verifying performance streams no data message") def is_no_performance_streams_message_shown(self): return wait(self.lb_performance_no_streams_message.is_present) @allure.step("Verifying market selector value on performance section") def is_user_market_on_performance_section(self, market): locator = f"**/XCUIElementTypeOther[`label CONTAINS '{market.upper()} KPIS '`]" return self.is_element_displayed(locator, "class-chain") @allure.step("Verifying market selector value on performance section") def is_user_market_on_performance_section_apple(self, market): locator = f"**/XCUIElementTypeOther[`label CONTAINS '{market.upper()} Owner '`]" return self.is_element_displayed(locator, "class-chain") def is_date_picker_opened_playlist(self): return self.lb_date_picker_title.is_visible() and self.bn_date_picker_done.is_visible() and self.bn_date_picker_2_weeks.is_visible() @allure.step("Verifying info popup is opened") def is_playlists_popup_opened(self): return self.lb_playlist_popup_text.is_visible() @allure.step("Verifying the text in popup is opened") def is_playlists_text_popup_opened(self): return self.lb_playlist_popup_text_full.is_visible() @allure.step("Verifying the detailed streams graph is closed") def is_detailed_view_graph_closed(self): self.bn_streams_detailed.wait(to_assert=False) orientation = self.driver.orientation return orientation == "PORTRAIT" @allure.step("Verifying market indicator is displayed on detailed market screen") def is_market_indicator_displayed(self, market): locator = f"**/XCUIElementTypeOther[`label CONTAINS '{market} Streams'`]" return self.is_element_displayed(locator, "class-chain") @allure.step("Verifying market indicator is displayed on detailed market screen") def is_listeners_market_indicator_displayed(self, market): locator = f"**/XCUIElementTypeOther[`label CONTAINS '{market} Listeners'`]" return self.is_element_displayed(locator, "class-chain") @allure.step("Verifying % of Global section in popup") def is_percent_of_global_displayed(self): return self.lb_percent_of_global.is_present()