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 selenium.common.exceptions import NoSuchElementException from ui_automation_framework.utils import logger as cl from waiting import TimeoutExpired from app.src.helpers.data_formaters import DataFormatter from app.src.helpers.waiting_wrapper import wait from app.src.pages.navigation_page import Navigation 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 TrackPage(Navigation): log = cl.Logger(logging.DEBUG) PLAYLIST_BY_POSITION_LOCATOR = "**/XCUIElementTypeScrollView/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther[2]" "/XCUIElementTypeOther/XCUIElementTypeOther[{}]" PLAYLIST_BY_TEXT_LOCATOR = '**/XCUIElementTypeOther[`name == "shared-touchable-card" AND label BEGINSWITH "{}"`]' PLAYLIST_BY_TEXT_LOCATOR_WITH_PERSONALIZED_LABEL = '**/XCUIElementTypeOther[`name == "shared-touchable-card" AND label BEGINSWITH "{}" AND label CONTAINS "PERSONALIZED"`]' def __init__(self, driver, api_client): super().__init__(driver) self.driver = driver self.track_locators = self.get_page_locators("TrackPage", "track_elements.json") self.api = api_client @property def bn_track_info(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "track_info_button")) @property def lb_markets_title(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "markets_title")) @property def lb_starred_label(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "starred_label")) @property def lb_unstarred_label(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "unstarred_label")) @property def bn_youtube(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "youtube_btn")) @property def bn_tiktok(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "tiktok_btn")) @property def bn_markets_popup(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "markets_popup")) @property def lb_markets_popup_text(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "markets_popup_text")) @property def bn_show_playlists(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "show_playlists")) @property def bn_charts_popup(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "charts_popup")) @property def bn_playlist_popup(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "playlist_popup")) @property def bn_streams_popup(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "streams_popup")) @property def lb_streams_overview_popup_text(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "streams_overview_popup_text")) @property def bn_audience_popup(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "audience_popup")) @property def bn_monitoring_popup(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "monitoring_popup")) @property def lb_streams_monitoring_popup_text(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "streams_monitoring_popup_text")) @property def bn_detailed_market(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "detailed_market")) @property def bn_global_market_card(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "global_market_card")) @property def bn_date_picker(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "date_picker")) @property def bn_date_range_selector(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "date_range_selector")) @property def bn_combined_streams_details(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "combined_streams_details_btn")) @property def bn_amazon_streams_details(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "amazon_streams_details_btn")) @property def bn_close_detailed_view(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "close_detailed_view_btn")) @property def lb_streams_label(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "streams_label")) @property def bn_first_spotify_playlist_card(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "first_spotify_playlist_card")) @property def bn_spotify_link(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "spotify_link")) @property def bn_apple_link(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "apple_link")) @property def bn_latest_adds_playlist_card(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "latest_adds_playlist_card")) @property def bn_demographic_tile_1(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "demographic_tile_1_xpath")) @property def bn_demographic_tile_2(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "demographic_tile_2_xpath")) @property def bn_demographic_tile_4(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "demographic_tile_4_xpath")) @property def bn_demographic_tile_3(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "demographic_tile_3")) @property def bn_track_header(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "track_header")) @property def bn_top_markets_show_all(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "top_markets_show_all_btn")) @property def bn_charts_spotify(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "charts_spotify")) @property def bn_charts_apple(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "charts_apple")) @property def bn_market_selector(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "market_selector")) @property def bn_select_market(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "select_market_btn")) @property def bn_info_playlists_icon(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "info_playlists_icon")) @property def bn_info_latest_adds_icon(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "info_latest_adds_icon")) @property def bn_latest_removals_i_icon(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "latest_removals_i_icon")) @property def bn_info_top_5_icon(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "info_top_5_icon")) @property def bn_clear_search_icon(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "clear_search_icon")) @property def bn_markets_done(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "markets_done_btn")) @property def bn_markets_cancel(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "markets_cancel_btn")) @property def bn_date_picker_2_weeks(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "date_picker_2_weeks")) @property def bn_date_picker_done(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "date_picker_done")) @property def bn_date_picker_4_weeks(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "date_picker_4_weeks")) @property def bn_date_picker_8_weeks(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "date_picker_8_weeks")) @property def bn_date_picker_12_weeks(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "date_picker_12_weeks")) @property def bn_date_picker_26_weeks(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "date_picker_26_weeks")) @property def bn_date_picker_1_year(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "date_picker_1_year")) @property def bn_clear(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "clear_button")) @property def bn_streams_monitoring_spotify(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "streams_monitoring_spotify")) @property def bn_hh_widget(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "hot_hits_widget_button")) @property def lb_card_last_date_date(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "card_last_date_date")) @property def lb_card_last_date_value(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "card_last_date_value")) @property def lb_card_last_date_trend(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "card_last_date_trend")) @property def lb_card_last_date_trend_icon(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "card_last_date_trend_icon")) @property def lb_card_last_week_value(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "card_last_week_value")) @property def lb_card_last_week_trend(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "card_last_week_trend")) @property def lb_card_last_week_trend_icon(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "card_last_week_trend_icon")) @property def lb_card_last_week_dates(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "card_last_week_dates")) @property def lb_card_past_chart_week_date(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "card_past_chart_week_date")) @property def lb_card_past_chart_week_value(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "card_past_chart_week_value")) @property def lb_card_past_chart_week_trend_icon(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "card_past_chart_week_trend_icon")) @property def lb_card_actual_chart_week_date(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "card_actual_chart_week_date")) @property def lb_card_actual_chart_week_value(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "card_actual_chart_week_value")) @property def lb_card_past_chart_week_trend(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "card_past_chart_week_trend")) @property def lb_card_all_time_value(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "card_all_time_value")) @property def lb_market_card_data(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "market_card_data")) @property def lb_lean_back_value(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "lean_back_value")) @property def lb_lean_forward_value(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "lean_forward_value")) @property def lb_lean_back_streams_value(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "lean_back_streams_value")) @property def lb_lean_forward_streams_value(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "lean_forward_streams_value")) @property def lb_demographics_age_block_1(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "demographics_age_block_1")) @property def lb_demographics_age_block_2(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "demographics_age_block_2")) @property def lb_demographics_tile_content(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "demographics_tile_content")) @property def lb_by_age_data(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "by_age_data")) @property def lb_apple_value(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "apple_value")) @property def lb_amazon_value(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "amazon_value")) @property def lb_spotify_value(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "spotify_value")) @property def lb_dsp_latency_title(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "dsp_latency_title")) @property def lb_dsp_global_lines(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "dsp_global_lines")) @property def lb_dsp_latency_global_title(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "dsp_latency_global_title")) @property def lb_no_demographics_all(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "no_demographics_all")) @property def lb_demographics_popup_heading(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "demographics_popup_heading")) @property def lb_by_gender_demographics_title(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "by_gender_demographics_title")) @property def lb_no_apple_demographics(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "no_apple_demographics")) @property def lb_demographic_tile_1(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "demographic_tile_1")) @property def lb_demographic_tile_2(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "demographic_tile_2")) @property def lb_global_streams(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "global_streams")) @property def lb_combined_streams_legend(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "combined_streams_legend")) @property def lb_dsp_streams_legend(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "dsp_streams_legend")) @property def lb_markets_popup_text_2(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "markets_popup_text_2")) @property def lb_markets_popup_text_3(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "markets_popup_text_3")) @property def lb_markets_popup_text_4(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "markets_popup_text_4")) @property def lb_charts_placements_popup_text(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "charts_placements_popup_text")) @property def lb_charts_placements_popup_text_1(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "charts_placements_popup_text_1")) @property def lb_streams_overview_popup_text_1(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "streams_overview_popup_text_1")) @property def lb_audience_popup_text(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "audience_popup_text")) @property def lb_audience_popup_text_1(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "audience_popup_text_1")) @property def lb_audience_popup_text_2(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "audience_popup_text_2")) @property def lb_audience_popup_text_3(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "audience_popup_text_3")) @property def lb_streams_monitoring_popup_text_1(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "streams_monitoring_popup_text_1")) @property def lb_streams_monitoring_popup_text_2(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "streams_monitoring_popup_text_2")) @property def lb_streams_monitoring_popup_text_3(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "streams_monitoring_popup_text_3")) @property def lb_spotify_unavailable(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "spotify_unavailable")) @property def lb_apple_unavailable(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "apple_unavailable")) @property def lb_markets_global_unavailable(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "markets_global_unavailable")) @property def lb_us_card(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "us_card")) @property def lb_markets_us_unavailable(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "markets_us_unavailable")) @property def lb_no_charts_search_results_msg(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "no_charts_search_results_msg")) @property def lb_empty_charts(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "empty_charts")) @property def lb_combined_streams_card(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "combined_streams_card")) @property def lb_streams_monitoring_sircle_date(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "streams_monitoring_sircle_date")) @property def lb_charts_title(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "charts_title")) @property def lb_spotify_streams_count(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "spotify_streams_count")) @property def lb_apple_streams_count(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "apple_streams_count")) @property def lb_amazon_streams_count(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "amazon_streams_count")) @property def lb_playlists_popup_text(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "playlists_popup_text")) @property def lb_playlists_popup_title(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "playlists_popup_title")) @property def lb_latest_adds_popup_title(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "latest_adds_popup_title")) @property def lb_latest_removals_i_popup_title(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "latest_removals_i_popup_title")) @property def lb_latest_removals_i_popup_text(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "latest_removals_i_popup_text")) @property def lb_top_5_popup_text(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "top_5_popup_text")) @property def lb_no_streams_dsp(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "no_streams_dsp")) @property def lb_no_streams_all(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "no_streams_all")) @property def lb_no_streams_apple(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "no_streams_apple")) @property def lb_no_spotify_playlists_msg(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "no_spotify_playlists_msg")) @property def lb_no_spotify_latest_adds_msg(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "no_spotify_latest_adds_msg")) @property def lb_no_spotify_top_5_msg(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "no_spotify_top_5_msg")) @property def lb_no_apple_playlists_msg(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "no_apple_playlists_msg")) @property def lb_no_apple_latest_adds_msg(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "no_apple_latest_adds_msg")) @property def lb_no_apple_top_5_msg(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "no_apple_top_5_msg")) @property def lb_no_stremas_streams_overview(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "no_stremas_streams_overview")) @property def lb_no_stremas_demographics(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "no_stremas_demographics")) @property def lb_no_stremas_monitoring(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "no_stremas_monitoring")) @property def lb_track_is_unavailable(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "track_is_unavailable")) @property def bn_streams_monitoring_apple(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "streams_monitoring_apple")) @property def bn_streams_monitoring_amazon(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "streams_monitoring_amazon")) @property def bn_streams_monitoring_by_dsp(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "streams_monitoring_by_dsp")) @property def bn_streams_performance_card(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "streams_performance_card")) @property def lb_streams_performance_card_spotify(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "streams_performance_card_spotify")) @property def lb_streams_performance_card_apple(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "streams_performance_card_apple")) @property def lb_streams_performance_card_amazon(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "streams_performance_card_amazon")) @property def lb_streams_monitoring_card(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "streams_monitoring_card")) @property def bn_date_picker_button(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "date_picker_button")) @property def lb_track_image(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "track_image")) @property def lb_track_title_area(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "track_title_area")) @property def lb_no_youtube_and_tiktok_videos_available_text(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "no_youtube_and_tiktok_videos_available_text")) @property def bn_local_market_card(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "local_market_card"), "Local market card") @property def lt_demographics_age_blocks(self): return ListUIElement( self.driver, all_elements_locator=( MobileBy.IOS_CLASS_CHAIN, "**/XCUIElementTypeScrollView[4]/XCUIElementTypeOther/XCUIElementTypeOther", ), ) @property def in_charts_search(self): return InputUIElement(self.driver, self.locator(self.track_locators, "charts_search")) @property def lb_latest_adds_popup_text(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "latest_adds_popup_text")) @property def bn_spotify_streams_details(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "spotify_streams_details_btn")) @property def bn_apple_streams_details(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "apple_streams_details_btn")) @property def lb_date_picker_title(self): return LabelUIElement(self.driver, self.locator(self.track_locators, "date_picker_title")) @property def bn_top_5_playlist_card(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "top_5_playlist_card")) @property def bn_global_card(self): return ButtonUIElement(self.driver, self.locator(self.track_locators, "global_card")) @property def in_markets_search(self): return InputUIElement(self.driver, self.locator(self.track_locators, "markets_search_field")) @property def lt_personalized_playlist_card(self): return ListUIElement( self.driver, all_elements_locator=( MobileBy.IOS_CLASS_CHAIN, self.locator(self.track_locators, "personalized_playlist_card")[0], ), ) @property def in_playlists_search(self): return InputUIElement(self.driver, self.locator(self.track_locators, "playlists_search")) @property def lt_latest_adds_cards(self): return ListUIElement( self.driver, all_elements_locator=(MobileBy.IOS_CLASS_CHAIN, self.locator(self.track_locators, "lastest_adds_cards")[0]), ) @property def lt_playlists(self): return ListUIElement( self.driver, all_elements_locator=(MobileBy.IOS_CLASS_CHAIN, self.locator(self.track_locators, "playlists")[0]), ) @property def lt_markets(self): return ListUIElement(self.driver, by_text_locator=(MobileBy.IOS_CLASS_CHAIN, "**/XCUIElementTypeOther[`label == '{}'`]")) @property def lb_charts_placement(self): return LabelUIElement( self.driver, ('**/XCUIElementTypeStaticText[`label == "Chart Placements"`]', "class-chain"), ) @allure.step("Marking track with a star") def star_track(self): self.lb_markets_title.wait(to_assert=False) size = self.driver.get_window_size() TouchAction(self.driver).tap(x=size["width"] * 0.91, y=size["height"] * 0.096).perform() self.lb_starred_label.wait(to_assert=False) return self @allure.step("Tapping 'X' or Back to close track page") def close_track_page(self): time.sleep(1) size = self.driver.get_window_size() self.log.info(size) TouchAction(self.driver).tap(x=size["width"] * 0.091, y=size["height"] * 0.096).perform() return self @allure.step("Un-starring track") def unstar_track(self): self.lb_markets_title.wait(to_assert=False) size = self.driver.get_window_size() TouchAction(self.driver).tap(x=size["width"] * 0.91, y=size["height"] * 0.096).perform() self.lb_unstarred_label.wait(to_assert=False) return self @allure.step("Opening markets 'i' popup") def open_markets_popup(self): self.bn_markets_popup.click() self.lb_markets_popup_text.wait(to_assert=False) return self @allure.step("Opening playlists page") def open_playlists(self): self.bn_show_playlists.click(to_assert=False, timeout=30) return self @allure.step("Opening charts 'i' popup") def open_charts_placements_popup(self): self.bn_charts_popup.click() return self @allure.step("Opening playlist 'i' popup") def open_playlists_information_popup(self): self.bn_playlist_popup.click() time.sleep(1) return self @allure.step("Opening streams overview 'i' popup") def open_streams_overview_popup(self): self.bn_streams_popup.click() self.lb_streams_overview_popup_text.wait(to_assert=False) return self @allure.step("Opening audience demographics 'i' popup") def open_audience_popup(self): self.bn_audience_popup.click() time.sleep(1) return self @allure.step("Opening streams monitoring 'i' popup") def open_streams_monitoring_popup(self): self.bn_monitoring_popup.click() self.lb_streams_monitoring_popup_text.wait(to_assert=False) return self @allure.step("Opening detailed market information screen") def open_market_detailed_view(self): self.bn_detailed_market.click() time.sleep(1) return self @allure.step("Opening market detailed page") def open_market_detailed_page(self): self.lb_markets_title.wait(to_assert=False) self.bn_global_market_card.click() return self @allure.step("Opening market specific market detailed page") def open_market_specific_market_detailed_page(self): self.lb_markets_title.wait(to_assert=False) self.bn_local_market_card.click() return self @allure.step("Opening date selector") def open_date_picker(self): self.bn_date_picker.click() return self @allure.step("Opening date range selector") def open_date_range_selector(self): self.bn_date_range_selector.click() return self @allure.step("Opening detailed view for combined streams") def open_combined_streams_detailed_view(self): self.bn_combined_streams_details.click() return self @allure.step("Opening detailed view for spotify stream") def open_spotify_stream_detailed_view(self): self.bn_spotify_streams_details.click() return self @allure.step("Opening detailed view for apple stream") def open_apple_stream_detailed_view(self): self.bn_spotify_streams_details.swipe_left_long() self.bn_apple_streams_details.click() return self @allure.step("Swipe for detailed view (spotify stream)") def swipe_spotify_stream_detailed_view(self): self.bn_spotify_streams_details.swipe_left_long() self.bn_spotify_streams_details.wait(to_assert=False) return self @allure.step("Swipe for detailed view (apple stream)") def swipe_apple_stream_detailed_view(self): self.bn_spotify_streams_details.swipe_left_long() self.bn_apple_streams_details.wait(to_assert=False) return self @allure.step("Swipe for detailed view (amazon stream)") def swipe_amazon_stream_detailed_view(self): self.bn_spotify_streams_details.swipe_left_long() self.bn_amazon_streams_details.wait(to_assert=False) return self @allure.step("Opening detailed view for amazon stream") def open_amazon_stream_detailed_view(self): self.bn_apple_streams_details.swipe_left_long() self.bn_amazon_streams_details.click() return self @allure.step("Closing streams overview detailed view") def close_streams_overview_detailed_view(self): self.bn_close_detailed_view.click() return self @allure.step("Tap on streams overview graph for detailed info") def tap_streams_overview_for_detailed_info(self): self.lb_streams_label.wait(to_assert=False) size = self.driver.get_window_size() actions = TouchAction(self.driver) actions.press(x=size["width"] / 2, y=size["height"] / 1.8).wait(4000) actions.move_to(x=size["width"] / 2, y=size["height"] / 4).wait(4000) actions.perform() return self @allure.step("Tap on streams default graph") def tap_streams_default_view(self): self.bn_streams_popup.wait(to_assert=False) size = self.driver.get_window_size() actions = TouchAction(self.driver) actions.press(x=size["width"] / 2, y=size["height"] / 2).wait(4000) actions.move_to(x=size["width"] / 2, y=size["height"] / 2).wait(4000) actions.perform() return self @allure.step("Tap on the beginning of streams overview graph for detailed info") def tap_beginning_of_the_graph(self): self.lb_streams_label.wait(to_assert=False) size = self.driver.get_window_size() actions = TouchAction(self.driver) actions.press(x=size["width"] / 7, y=size["height"] / 1.8).wait(4000) actions.move_to(x=size["width"] / 7, y=size["height"] / 4).wait(4000) actions.perform() return self @allure.step("Clicking on playlist card spotify") def click_playlist_card_spotify(self): self.bn_first_spotify_playlist_card.click() return self @allure.step("Clicking on spotify link in track info") def click_spotify_partner_link(self): self.bn_spotify_link.click() return self @allure.step("Clicking on apple link in track info") def click_apple_partner_link(self): self.bn_apple_link.click() return self @allure.step("Clicking on a playlist from the list") def click_on_playlist_by_position(self, position): # locator = self.PLAYLIST_BY_POSITION_LOCATOR.format(position) locator = "**/XCUIElementTypeOther[`name == 'shared-touchable-card'`][{}]".format(position) self.wait_for_element_visible(locator, "class-chain") self.click_element(locator, "class-chain") return self def click_in_playlist_by_text(self, text, is_parametrized=False): if not is_parametrized: locator = self.PLAYLIST_BY_TEXT_LOCATOR.format(text) else: locator = self.PLAYLIST_BY_TEXT_LOCATOR_WITH_PERSONALIZED_LABEL.format(text) self.wait_for_element_visible(locator, "class-chain") self.click_element(locator, "class-chain") @allure.step("Clicking on a playlist from top 5 playlists sectrion") def click_on_playlist_from_top_5(self): self.bn_top_5_playlist_card.click() return self @allure.step("Clicking on a playlist from Latest Adds") def click_on_playlist_from_latest_adds(self): wait(self.bn_latest_adds_playlist_card.is_present) self.bn_latest_adds_playlist_card.click() return self @allure.step("Clicking on demographics gender tile") def click_audience_demographics_tile_1(self): self.bn_demographic_tile_1.click() return self @allure.step("Clicking on demographics gender tile") def click_audience_demographics_tile_2(self): self.bn_demographic_tile_2.click() return self @allure.step("Clicking on demographics gender tile") def click_audience_demographics_tile_4(self): self.bn_demographic_tile_4.click() return self @allure.step("Clicking on demographics gender tile") def click_audience_demographics_tile_3(self): self.bn_demographic_tile_3.click() return self @allure.step("Clicking on the page header") def click_header(self, track_name): locator = f"**/XCUIElementTypeOther[`label CONTAINS \"{track_name}\"`][2]" self.click_element(locator, "class-chain") return self @allure.step("Clicking on a playlist element") def click_on_playlist(self, playlist_element): self.click_element(element=playlist_element) return self @allure.step("Clicking top 5 markets show all button") def click_top_5_show_all(self): self.bn_top_markets_show_all.click(timeout=5) return self @allure.step("Opening spotify charts pacements") def click_spotify_charts(self): self.bn_charts_spotify.click() return self @allure.step("Opening apple charts pacements") def click_apple_charts(self): self.bn_charts_apple.click() return self @allure.step("Clicking on market selector") def click_market_selector(self): self.bn_market_selector.click() return self @allure.step("Clicking on market selection button") def click_select_market_button(self): self.driver.execute_script("mobile: scroll", {"direction": "down", "distance": 0.1}) self.bn_select_market.click() return self @allure.step("Clicking playlists info icon") def click_playlists_info_icon(self): self.bn_info_playlists_icon.click() return self @allure.step("Clicking latest adds info icon") def click_lastest_adds_info_icon(self): self.bn_info_latest_adds_icon.click() return self @allure.step("Clicking latest removals info icon") def click_lastest_removals_info_icon(self): self.bn_latest_removals_i_icon.click() return self @allure.step("Clicking top 5 playlists info icon") def click_top_5_playlists_info_icon(self): self.bn_info_top_5_icon.click() return self @allure.step("Clicking Hot Hits widget") def click_hot_hits_widget(self): self.bn_hh_widget.click() return self @allure.step("Scrolling down the track page") def scroll_to_playlists(self): scroll_object = {} scroll_object.update({"direction": "up"}) scroll_object.update({"xpath": "//XCUIElementTypeStaticText[@label='Playlist Information']"}) self.driver.execute_script("mobile: swipe", scroll_object) # self.scroll_down() return self @allure.step("Scrolling to the top 5 playlists section") def scroll_to_top_5_playlists(self): scroll_object = {} scroll_object.update({"direction": "up"}) scroll_object.update({"xpath": '//XCUIElementTypeOther[@name="top-playlists-touchable-card"][1]'}) self.driver.execute_script("mobile: swipe", scroll_object) return self @allure.step("Scrolling to the lates adds section") def scroll_to_playlists_latest_adds(self): scroll_object = {} scroll_object.update({"direction": "up"}) scroll_object.update({"class-chain": '**/XCUIElementTypeOther[`name == "shared-touchable-card"`][1]'}) self.driver.execute_script("mobile: swipe", scroll_object) return self @allure.step("Scrolling down the track page") def scroll_to_chart_placements(self): self.lb_markets_title.wait(to_assert=False) self.driver.scroll(self.lb_markets_title._element, self.lb_charts_placement._element) self.lb_markets_title.wait_for_same_place() return self @allure.step("Open track info") def open_track_info(self): self.bn_track_info.click() return self @allure.step("Searching and opening personalazed playlist") def find_and_open_personalized_playlist(self): element = wait(lambda: self.lt_personalized_playlist_card.elements)[0] element.scroll_to() element.click() return self @allure.step("Scrolling down the track page") def scroll_to_streams_monitoring(self): locator = '//XCUIElementTypeOther[@label="SPOTIFY APPLE MUSIC AMAZON BY DSP"]' self.wait_for_element_present(locator, "xpath") scroll_object = {} scroll_object.update({"direction": "up"}) scroll_object.update({"xpath": f"{locator}"}) self.driver.execute_script("mobile: swipe", scroll_object) return self # TODO refactor this as locator probably changed and wait is required before scroll @allure.step("Scrolling down the track page") def scroll_to_demographics(self): scroll_object = {} scroll_object.update({"direction": "up"}) scroll_object.update( { "xpath": "//XCUIElementTypeOther[@label='SPOTIFY APPLE MUSIC']/../XCUIElementTypeOther[contains(@label," " 'UNKNOWN ')]/XCUIElementTypeOther[contains(@label, 'UNKNOWN ')]/XCUIElementTypeOther[con" "tains(@label, 'UNKNOWN ')]/XCUIElementTypeOther[contains(@label, 'UNKNOWN ')]" "/XCUIElementTypeOther[contains(@label, 'UNKNOWN ')]" } ) self.driver.execute_script("mobile: swipe", scroll_object) time.sleep(1) return self @allure.step("Scrolling playlists page") def scroll_on_the_playlists(self): self.driver.execute_script("mobile: scroll", {"direction": "down"}) 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("Scrolling charts page") def scroll_on_the_charts(self): self.driver.execute_script("mobile: scroll", {"direction": "down"}) self.driver.execute_script("mobile: scroll", {"direction": "down"}) self.driver.execute_script("mobile: scroll", {"direction": "down"}) self.driver.execute_script("mobile: scroll", {"direction": "down"}) @allure.step("Swiping streams cards") def swipe_streams_cards(self): self.bn_global_card.swipe_left_long() return self @allure.step("Swiping top 5 playlists") def swipe_top_5_playlists(self): self.bn_top_5_playlist_card.swipe_left_long() return self @allure.step("Searching for a playlist") def search_for_playlist(self, query): self.in_playlists_search.wait(to_assert=False) self.in_playlists_search.clear_text() self.in_playlists_search.send_text(query) return self @allure.step("Searching for country in charts placements") def search_in_charts(self, query): self.in_charts_search.send_text(query) return self @allure.step("Clearing a search field") def click_clear_search_icon(self): self.bn_clear_search_icon.click() return self @allure.step("Selecting market from the list") def select_market_from_the_list(self, market): element = self.lt_markets.get_item_by_text(market) # element.wait(to_assert=False) # element.scroll_to() element.click() self.bn_markets_done.click() return self @allure.step("Selecting DSP") def select_playlist_dsp(self, dsp_name): dsp_locator = "**/XCUIElementTypeOther[`label == 'SPOTIFY APPLE MUSIC AMAZON'`]/XCUIElementTypeOther[`label =='{}'`]".format(dsp_name.upper()) self.wait_for_element_present(dsp_locator, "class-chain") self.click_element(dsp_locator, "class-chain") return self @allure.step("Selecting market from the list and cancel selection") def select_market_from_the_list_and_cancel(self, market): market = self.lt_markets.get_item_by_text(market) # market.wait(to_assert=False) # market.scroll_to() market.click() self.bn_markets_cancel.click() return self @allure.step("Selecting DSP on demographics section") def select_demographics_dsp(self, DSP): dsp_locator = "**/XCUIElementTypeOther[`label == '{}'`]".format(DSP.upper()) self.click_element(dsp_locator, "class-chain") # definitely a bad practice, but haven't any specific conditions to verify if state is changed time.sleep(2) return self @allure.step("Selecting 2 weeks date range") def select_2_weeks_date_filter(self): self.bn_date_picker_2_weeks.click() self.bn_date_picker_done.click() 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 rage") 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 1 year date range") def select_1_year_date_filter(self): self.bn_date_picker_1_year.click() self.bn_date_picker_done.click() return self @allure.step("Selecting 1 year date range but not submitting") def click_1_year_date_filter_without_submit(self): self.bn_date_picker_1_year.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_markets_search.send_text(query) locator = "//XCUIElementTypeScrollView/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther" "/XCUIElementTypeOther[contains (@label, '{}')]" self.click_element(locator.format(query), "xpath") self.bn_markets_done.click() return self @allure.step("Selecting market via the search field") def select_market_via_search_without_done(self, query): self.bn_markets_done.wait(to_assert=False) self.in_markets_search.send_text(query) return self @allure.step("Clearing the search field") def clear_search_field(self): self.bn_clear.click() self.close_keyboard_by_swipe() return self @allure.step("Selecting spotify tab in stream monitoring") def select_stream_monitoring_spotify_tab(self): self.bn_streams_monitoring_spotify.click() # self.driver.execute_script("mobile: scroll", {"element": element, "toVisible": True}) return self @allure.step("Selecting apple tab in stream monitoring") def select_stream_monitoring_apple_tab(self): self.bn_streams_monitoring_apple.click() # self.driver.execute_script("mobile: scroll", {"element": element, "toVisible": True}) return self @allure.step("Selecting amazon tab in stream monitoring") def select_stream_monitoring_amazon_tab(self): self.bn_streams_monitoring_amazon.click() # self.driver.execute_script("mobile: scroll", {"element": element, "toVisible": True}) return self @allure.step("Selecting DSP tab in stream monitoring") def select_stream_monitoring_by_dsp_tab(self): self.bn_streams_monitoring_by_dsp.click() # self.driver.execute_script("mobile: scroll", {"element": element, "toVisible": True}) return self @allure.step("Getting data from track performance streams card (Apple)") def get_streams_default_plot_data_apple(self): return self.lb_apple_streams_count.visible_text @allure.step("Getting data from track performance streams card (Amazon)") def get_streams_default_plot_data_amazon(self): return self.lb_amazon_streams_count.visible_text @allure.step("Getting data from track performance streams card (Spotify)") def get_streams_default_plot_data_spotify(self): return self.lb_spotify_streams_count.visible_text @allure.step("Getting data from track performance combined streams card") def get_streams_default_plot_data_combined(self): return self.lb_combined_streams_card.visible_text @allure.step("Getting playlist name") def get_playlist_name_by_position(self, position): locator = "**/XCUIElementTypeOther[`name == 'shared-touchable-card'`][{}]".format(position) self.wait_for_element_visible(locator, "class-chain") # name = self.get_text(locator, "class-chain").partition("Updated")[0].split() # formatted_name = " ".join(name[:-1]) # self.log.info(formatted_name) # return formatted_name name = self.get_text(locator, "class-chain").partition("#")[0] name = name.strip() self.log.info(name) return name @allure.step("Getting playlist data") def get_playlist_data_by_position(self, position): locator = "//XCUIElementTypeOther[@name='swipeable-playlist'][{}]".format(position) self.wait_for_element_visible(locator, "xpath") name = self.get_attribute_value(locator, "xpath", None, "label") self.log.info(name) return name @allure.step("Getting playlists search results") def get_playlists_search_results(self): # search_results = ( # "(//XCUIElementTypeScrollView/XCUIElementTypeOther/" # "XCUIElementTypeOther/XCUIElementTypeOther)[2]/XCUIElementTypeOther/XCUIElementTypeOther" # ) search_results = '//XCUIElementTypeOther[@name="shared-touchable-card"])' 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 chart title") def get_chart_title(self, position): locator = '(//XCUIElementTypeOther[@name="chart-placements-card"])[{}]/XCUIElementTypeOther[2]'.format(position) self.wait_for_element_visible(locator, "xpath") title = self.get_attribute_value(locator, "xpath", None, "label") self.log.info(title) return title @allure.step("Getting charts placements data") def get_chart_placements_data(self): locator = '//XCUIElementTypeOther[@name="chart-placements-card"]' self.wait_for_element_visible(locator, "xpath") chart_cards = self.get_elements(locator, "xpath") cards_data = [self.get_text(element=chart) for chart in chart_cards] self.log.info(cards_data) return cards_data @allure.step("Getting name from playlist element") def get_playlist_name_by_element(self, playlist_element): return self.get_text(element=playlist_element).split()[0] @allure.step("Get playlists elements") def get_playlists(self): return [p.element for p in wait(lambda: self.lt_playlists.elements)] @allure.step("Getting playlist name on top 5 section") def get_top_5_playlist_title(self): name_list = self.bn_top_5_playlist_card.text.partition("Updated")[0].split()[:-1] return " ".join(name_list) @allure.step("Getting playlist card data on top 5 section") def get_top_5_playlist_data(self, position): locator = f'**/XCUIElementTypeOther[`name == "top-playlists-touchable-card"`][{position}]' data = self.get_text(locator, "class-chain") return data @allure.step("Getting playlist latest adds title") def get_latest_adds_playlist_title(self, position): locator = f'**/XCUIElementTypeOther[`name BEGINSWITH "Latest Adds"`]/**/XCUIElementTypeOther[`name == "shared-touchable-card"`][{position}]' text = self.get_text(locator, "class-chain") if "PERSONALIZED" not in text: data = self.get_text(locator, "class-chain").partition("#")[0] return data.strip() else: data = self.get_text(locator, "class-chain").partition("PERSONALIZED")[0] return data.strip() @allure.step("Getting playlist latest adds card data") def get_latest_adds_playlist_data(self, position): locator = f'**/XCUIElementTypeOther[`label BEGINSWITH "Latest Adds"`]/**/XCUIElementTypeOther[`name == "shared-touchable-card"`][{position}]' element = self.wait_for_element_present(locator, "class-chain") data = self.get_text(element=element) return data @allure.step("Getting playlist latest adds card data") def get_latest_removals_data(self, position): locator = f'**/XCUIElementTypeOther[`name BEGINSWITH "Playlist Information"`]/XCUIElementTypeOther[8]/**/XCUIElementTypeOther[`name == "shared-touchable-card"`][{position}]' element = self.wait_for_element_present(locator, "class-chain") data = self.get_text(element=element) return data @allure.step("Tap on the latest removal card by position") def tap_to_latest_removals_card(self, position): locator = f'**/XCUIElementTypeOther[`name BEGINSWITH "Playlist Information"`]/XCUIElementTypeOther[8]/**/XCUIElementTypeOther[`name == "shared-touchable-card"`][{position}]' element = self.wait_for_element_present(locator, "class-chain") element.click() @allure.step("Getting playlist number on top 5 section") def get_top_5_playlist_count(self): return len(self.get_elements("top-playlists-touchable-card")) @allure.step("Getting playlist number on lates adds section") def get_playlist_latest_adds_count(self): return len(self.lt_latest_adds_cards.elements) @allure.step("Getting global market card content") def get_global_market_card_content(self): self.bn_global_card.wait(to_assert=False) return self.bn_global_market_card.label.split(" ") @allure.step("Getting local market card content") def get_local_market_card_content(self): self.bn_global_card.wait(to_assert=False) self.bn_local_market_card.swipe_left_long() return self.bn_local_market_card.label.split(" ") @allure.step("Getting 'last date' card date value") def get_last_date_card_date(self): self.lb_card_last_date_date.wait(to_assert=False) data = self.lb_card_last_date_date.label.partition(" AGAINST ") return data[0] @allure.step("Getting 'last date' card streams value") def get_last_date_card_value(self): self.lb_card_last_date_value.wait(to_assert=False) return self.lb_card_last_date_value.label @allure.step("Getting 'last date' card trend value") def get_last_date_card_trend(self): self.lb_card_last_date_trend.wait(to_assert=False) return self.lb_card_last_date_trend.label @allure.step("Getting 'last date' card trend icon") def get_last_date_card_trend_icon(self): self.lb_card_last_date_trend_icon.wait(to_assert=False) return self.lb_card_last_date_trend_icon.label @allure.step("Getting 'chart week' card streams value") def get_last_week_card_value(self): self.lb_card_last_week_value.wait(to_assert=False) return self.lb_card_last_week_value.label @allure.step("Getting 'chart week' card trend value") def get_last_week_card_trend(self): self.lb_card_last_date_trend.wait(to_assert=False) return self.lb_card_last_date_trend.label @allure.step("Getting 'chart week' card trend icon") def get_last_week_card_trend_icon(self): self.lb_card_last_week_trend_icon.wait(to_assert=False) return self.lb_card_last_week_trend_icon.label @allure.step("Getting 'chart week' card dates") def get_last_week_card_dates(self): self.lb_card_last_week_dates.wait(to_assert=False) return self.lb_card_last_week_dates.label @allure.step("Getting 'actual week' card date value") def get_past_chart_week_card_date(self): self.lb_card_past_chart_week_date.wait(to_assert=False) return self.lb_card_past_chart_week_date.label @allure.step("Getting 'actual week' card streams value") def get_past_chart_week_card_value(self): self.lb_card_past_chart_week_value.wait(to_assert=False) return self.lb_card_past_chart_week_value.label @allure.step("Getting 'actual week' card trend icon") def get_past_chart_week_card_trend_icon(self): self.lb_card_past_chart_week_trend_icon.wait(to_assert=False) return self.lb_card_past_chart_week_trend_icon.label @allure.step("Getting 'actual week' card date value") def get_actual_chart_week_card_date(self): self.lb_card_actual_chart_week_date.wait(to_assert=False) return self.lb_card_actual_chart_week_date.label @allure.step("Getting 'actual week' card streams value") def get_actual_chart_week_card_value(self): self.lb_card_actual_chart_week_value.wait(to_assert=False) with suppress(TimeoutExpired): return wait(lambda: self.lb_card_actual_chart_week_value.label, timeout=5, exceptions=NoSuchElementException) @allure.step("Getting 'actual week' card trend value") def get_past_chart_week_card_trend(self): self.lb_card_past_chart_week_trend.wait(to_assert=False) return self.lb_card_past_chart_week_trend.label @allure.step("Getting 'ALL TIME' card streams value") def get_all_time_card_value(self): self.lb_card_all_time_value.wait(to_assert=False) return self.lb_card_all_time_value.label @allure.step("Getting date picker dates") def get_date_picker_dates(self): dates = {} dates.update({"1 year": self.bn_date_picker_1_year.label.replace("1 Year ", "").replace(" ", "")}) dates.update({"2 weeks": self.bn_date_picker_2_weeks.label.replace("2 Weeks ", "").replace(" ", "")}) dates.update({"4 weeks": self.bn_date_picker_4_weeks.label.replace("4 Weeks ", "").replace(" ", "")}) dates.update({"8 weeks": self.bn_date_picker_8_weeks.label.replace("8 Weeks ", "").replace(" ", "")}) dates.update({"12 weeks": self.bn_date_picker_12_weeks.label.replace("12 Weeks ", "").replace(" ", "")}) dates.update({"26 weeks": self.bn_date_picker_26_weeks.label.replace("26 Weeks ", "").replace(" ", "")}) return dates @allure.step("Saving market name") def get_market_name_by_position(self, position): locator = ("//XCUIElementTypeScrollView/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/" "XCUIElementTypeOther[{}]").format(position) self.wait_for_element_visible(locator, "xpath") return self.get_attribute_value(locator, "xpath", None, "label").replace(" \ue922", "").replace("\ue92c ", "") @allure.step("Saving market name") def get_market_name_by_position_with_icons(self, position): locator = ("//XCUIElementTypeScrollView/XCUIElementTypeOther/XCUIElementTypeOther/XCUIElementTypeOther/" "XCUIElementTypeOther[{}]").format(position) self.wait_for_element_visible(locator, "xpath") return self.get_attribute_value(locator, "xpath", None, "label") @allure.step("Getting dates from market card") def get_market_card_dates(self): self.lb_market_card_data.wait(to_assert=False) data = self.lb_market_card_data.label.split() self.log.info(data[5] + " " + data[6]) return data[5] + " " + data[6] @allure.step("Verifying lean back and lean forward calculation") def are_lean_back_and_forward_values_100(self): lean_back = self.lb_lean_back_value.label.strip("()").replace("%", "").replace("~", "") lean_forward = self.lb_lean_forward_value.label.strip("()").replace("%", "").replace("~", "") return int(lean_forward) + int(lean_back) == 100 @allure.step("Get lean back/lean forward") def get_lean_back_lean_forward(self): return self.lb_lean_back_streams_value.label, self.lb_lean_forward_streams_value.label @allure.step("Getting calculated date") def get_api_dates(self, isrc, market): resp_daily = self.api.dsp.get_daily_and_weekly_streams_count("isrc={}".format(isrc), "market={}".format(market))["body"] resp_weekly = self.api.dsp.get_weekly_streams_count("isrc={}".format(isrc), "market={}".format(market))["body"] chart_week_start = datetime.datetime.strptime(resp_daily["dates"]["current_week"]["start"], "%Y-%m-%d").strftime("%m/%d/%y") chart_week_end = datetime.datetime.strptime(resp_daily["dates"]["current_week"]["end"], "%Y-%m-%d").strftime("%m/%d/%y") current_week_start = datetime.datetime.strptime(resp_daily["dates"]["rolling_week"]["start"], "%Y-%m-%d").strftime("%m/%d/%y") current_week_end = datetime.datetime.strptime(resp_daily["dates"]["rolling_week"]["end"], "%Y-%m-%d").strftime("%m/%d/%y") latest_date = datetime.datetime.strptime(resp_daily["dates"]["current_day"], "%Y-%m-%d").strftime("%m/%d/%y") rolling_week_start = datetime.datetime.strptime(resp_weekly["dates"]["current_week"]["start"], "%Y-%m-%d").strftime("%m/%d/%y") rolling_week_end = datetime.datetime.strptime(resp_weekly["dates"]["current_week"]["end"], "%Y-%m-%d").strftime("%m/%d/%y") current_week = current_week_start + "–" + current_week_end rolling_week = rolling_week_start + "–" + rolling_week_end chart_week = chart_week_start + "–" + chart_week_end is_current_chart_week_shown = datetime.datetime.strptime(resp_daily["dates"]["rolling_week"]["start"], "%Y-%m-%d") <= datetime.datetime.strptime(resp_daily["dates"]["current_day"], "%Y-%m-%d") return latest_date, current_week, rolling_week, chart_week, is_current_chart_week_shown @allure.step("Getting streams count from the API") def get_api_streams_count_market(self, isrc, market): resp_daily = self.api.dsp.get_daily_and_weekly_streams_count("isrc={}".format(isrc), "market={}".format(market))["body"] resp_week = self.api.dsp.get_weekly_streams_count("isrc={}".format(isrc), "market={}".format(market))["body"] chart_week = DataFormatter.round_streams(resp_daily["market_streams"]["current_week"]) rolling_week = DataFormatter.round_streams(resp_daily["market_streams"]["rolling_week"]) latest_date = DataFormatter.round_streams(resp_daily["market_streams"]["current_day"]) current_week = DataFormatter.round_streams(resp_week["market_streams"]["current_week"]) if chart_week[-2] == "0": chart_week = chart_week.replace(".0", "") if rolling_week != "0" and rolling_week[-2] == "0": rolling_week = rolling_week.replace(".0", "") if latest_date[-2] == "0": latest_date = latest_date.replace(".0", "") if current_week[-2] == "0": current_week = current_week.replace(".0", "") return chart_week, rolling_week, latest_date, current_week @allure.step("Getting data from track performance streams card (All vendors") def get_streams_performance_card_data(self): return self.bn_streams_performance_card.visible_text @allure.step("Getting data from track performance streams card (Spotify)") def get_streams_performance_card_data_spotify(self): return self.lb_streams_performance_card_spotify.visible_text @allure.step("Getting data from track performance streams card (Apple)") def get_streams_performance_card_data_apple(self): return self.lb_streams_performance_card_apple.visible_text @allure.step("Getting data from track performance streams card (Amazon)") def get_streams_performance_card_data_amazon(self): return self.lb_streams_performance_card_amazon.visible_text @allure.step("Getting streams count from the API") def get_api_streams_count_global(self, isrc, market): resp_daily = self.api.dsp.get_daily_and_weekly_streams_count("isrc={}".format(isrc), "market={}".format(market))["body"] resp_week = self.api.dsp.get_weekly_streams_count("isrc={}".format(isrc), "market={}".format(market))["body"] chart_week = DataFormatter.round_streams(resp_daily["global_streams"]["current_week"]) rolling_week = DataFormatter.round_streams(resp_daily["global_streams"]["rolling_week"]) latest_date = DataFormatter.round_streams(resp_daily["global_streams"]["current_day"]) current_week = DataFormatter.round_streams(resp_week["global_streams"]["current_week"]) if chart_week[-2] == "0": chart_week = chart_week.replace(".0", "") if rolling_week != "0" and rolling_week[-2] == "0": rolling_week = rolling_week.replace(".0", "") if latest_date[-2] == "0": latest_date = latest_date.replace(".0", "") if current_week[-2] == "0": current_week = current_week.replace(".0", "") return chart_week, rolling_week, latest_date, current_week @allure.step("Getting streams trends for streams overview") def get_api_streams_trends_global(self, isrc, market): resp_daily = self.api.dsp.get_daily_and_weekly_streams_count("isrc={}".format(isrc), "market={}".format(market))["body"] resp_week = self.api.dsp.get_weekly_streams_count("isrc={}".format(isrc), "market={}".format(market))["body"] last_streams_trend = round((resp_daily["global_streams"]["current_day"] - resp_daily["global_streams"]["prev_day"]) / resp_daily["global_streams"]["prev_day"] * 100) last_streams_week_trend = round((resp_week["global_streams"]["current_week"] - resp_week["global_streams"]["prev_week"]) / resp_week["global_streams"]["prev_week"] * 100) chart_week_streams_trend = round((resp_daily["global_streams"]["current_week"] - resp_daily["global_streams"]["prev_week"]) / resp_daily["global_streams"]["prev_week"] * 100) return last_streams_trend, last_streams_week_trend, chart_week_streams_trend @allure.step("Getting streams trends for streams overview") def get_api_streams_trends_market(self, isrc, market): resp_daily = self.api.dsp.get_daily_and_weekly_streams_count("isrc={}".format(isrc), "market={}".format(market))["body"] resp_week = self.api.dsp.get_weekly_streams_count("isrc={}".format(isrc), "market={}".format(market))["body"] last_streams_trend = round((resp_daily["market_streams"]["current_day"] - resp_daily["market_streams"]["prev_day"]) / resp_daily["market_streams"]["prev_day"] * 100) last_streams_week_trend = round((resp_week["market_streams"]["current_week"] - resp_week["market_streams"]["prev_week"]) / resp_week["market_streams"]["prev_week"] * 100) chart_week_streams_trend = round((resp_daily["market_streams"]["current_week"] - resp_daily["market_streams"]["prev_week"]) / resp_daily["market_streams"]["prev_week"] * 100) return last_streams_trend, last_streams_week_trend, chart_week_streams_trend @allure.step("Getting trends data from global market card") def get_global_market_trends_data(self): data = self.get_global_market_card_content() trends = [] arrows = [] for i in range(len(data)): if "%" in data[i]: trends.append(data[i]) arrows.append(data[i - 1]) return trends, arrows @allure.step("Getting trends data from global market card") def get_local_market_trends_data(self): data = self.get_local_market_card_content() trends = [] arrows = [] for i in range(len(data)): if "%" in data[i]: trends.append(data[i]) arrows.append(data[i - 1]) return trends, arrows @allure.step("Getting demographics data for spotify from apple api") def get_delphi_spotify_api_demographics(self, isrc, market): dates = self.bn_date_picker.text.replace(" ", "").split("–") start_date = datetime.datetime.strptime(dates[0], "%m/%d/%y").strftime("%Y-%m-%d") end_date = datetime.datetime.strptime(dates[1], "%m/%d/%y").strftime("%Y-%m-%d") resp = self.api.dsp.get_spotify_demographics_delphi( isrc, start_date, end_date, market, )["body"][ 0 ]["age_bands"] self.log.info(resp) age_0_17 = DataFormatter.round_streams(resp["all_0_17"]).upper() age_18_22 = DataFormatter.round_streams(resp["all_18_22"]).upper() age_23_27 = DataFormatter.round_streams(resp["all_23_27"]).upper() age_28_34 = DataFormatter.round_streams(resp["all_28_34"]).upper() age_35_44 = DataFormatter.round_streams(resp["all_35_44"]).upper() age_45_59 = DataFormatter.round_streams(resp["all_45_59"]).upper() age_60 = DataFormatter.round_streams(resp["all_60_150"]).upper() age_unkn = DataFormatter.round_streams(resp["all_unknown"]).upper() return [age_0_17, age_18_22, age_23_27, age_28_34, age_35_44, age_45_59, age_60, age_unkn] @allure.step("Getting demographics data for apple from apple api") def get_delphi_apple_api_demographics(self, isrc, market): dates = self.bn_date_picker.text.replace(" ", "").split("–") start_date = datetime.datetime.strptime(dates[0], "%m/%d/%y").strftime("%Y-%m-%d") end_date = datetime.datetime.strptime(dates[1], "%m/%d/%y").strftime("%Y-%m-%d") resp = self.api.dsp.get_apple_demographics_delphi(isrc, start_date, end_date, market)["body"][0]["age_bands"] self.log.info(resp) age_18_24 = DataFormatter.round_streams(resp["all_18_24"]).upper() age_25_34 = DataFormatter.round_streams(resp["all_25_34"]).upper() age_35_44 = DataFormatter.round_streams(resp["all_35_44"]).upper() age_45_54 = DataFormatter.round_streams(resp["all_45_54"]).upper() age_55_64 = DataFormatter.round_streams(resp["all_55_64"]).upper() age_65 = DataFormatter.round_streams(resp["all_65_plus"]).upper() age_unkn = DataFormatter.round_streams(resp["all_unknown"]).upper() return [age_18_24, age_25_34, age_35_44, age_45_54, age_55_64, age_65, age_unkn] @allure.step("Getting demographics data for from api") def get_delphi_spotify_api_demographics_by_gender(self, isrc, market, gender): dates = self.bn_date_picker.text.replace(" ", "").split("–") start_date = datetime.datetime.strptime(dates[0], "%m/%d/%y").strftime("%Y-%m-%d") end_date = datetime.datetime.strptime(dates[1], "%m/%d/%y").strftime("%Y-%m-%d") resp = self.api.dsp.get_spotify_demographics_delphi(isrc, start_date, end_date, market)["body"][0]["age_bands"] self.log.info(resp) age_0_17 = DataFormatter.round_streams_demographics(resp[f"{gender}_0_17"]).upper() age_18_22 = DataFormatter.round_streams_demographics(resp[f"{gender}_18_22"]).upper() age_23_27 = DataFormatter.round_streams_demographics(resp[f"{gender}_23_27"]).upper() age_28_34 = DataFormatter.round_streams_demographics(resp[f"{gender}_28_34"]).upper() age_35_44 = DataFormatter.round_streams_demographics(resp[f"{gender}_35_44"]).upper() age_45_59 = DataFormatter.round_streams_demographics(resp[f"{gender}_45_59"]).upper() age_60 = DataFormatter.round_streams_demographics(resp[f"{gender}_60_150"]).upper() age_unkn = DataFormatter.round_streams_demographics(resp[f"{gender}_unknown"]).upper() return age_0_17, age_18_22, age_23_27, age_28_34, age_35_44, age_45_59, age_60, age_unkn @allure.step("Getting demographics data for from api (Total listeners)") def get_delphi_spotify_api_demographics_by_gender_total(self, isrc, market, gender): dates = self.bn_date_picker.text.replace(" ", "").split("–") start_date = datetime.datetime.strptime(dates[0], "%m/%d/%y").strftime("%Y-%m-%d") end_date = datetime.datetime.strptime(dates[1], "%m/%d/%y").strftime("%Y-%m-%d") resp = self.api.dsp.get_spotify_demographics_delphi(isrc, start_date, end_date, market)["body"][0]["age_bands"] self.log.info(resp) age_0_17 = resp[f"{gender}_0_17"] age_18_22 = resp[f"{gender}_18_22"] age_23_27 = resp[f"{gender}_23_27"] age_28_34 = resp[f"{gender}_28_34"] age_35_44 = resp[f"{gender}_35_44"] age_45_59 = resp[f"{gender}_45_59"] age_60 = resp[f"{gender}_60_150"] age_unkn = resp[f"{gender}_unknown"] return sum([age_0_17, age_18_22, age_23_27, age_28_34, age_35_44, age_45_59, age_60, age_unkn]) @allure.step("Getting demographics data for from api (Total listeners)") def get_delphi_apple_api_demographics_by_gender_total(self, isrc, market, gender): dates = self.bn_date_picker.text.replace(" ", "").split("–") start_date = datetime.datetime.strptime(dates[0], "%m/%d/%y").strftime("%Y-%m-%d") end_date = datetime.datetime.strptime(dates[1], "%m/%d/%y").strftime("%Y-%m-%d") resp = self.api.dsp.get_apple_demographics_delphi(isrc, start_date, end_date, market)["body"][0]["age_bands"] self.log.info(resp) age_18_24 = resp[f"{gender}_18_24"] age_25_34 = resp[f"{gender}_25_34"] age_35_44 = resp[f"{gender}_35_44"] age_45_54 = resp[f"{gender}_45_54"] age_55_64 = resp[f"{gender}_55_64"] age_65 = resp[f"{gender}_65_plus"] age_unkn = resp[f"{gender}_unknown"] return sum([age_18_24, age_25_34, age_35_44, age_45_54, age_55_64, age_65, age_unkn]) @allure.step("Getting demographics data for from api") def get_delphi_apple_api_demographics_by_gender(self, isrc, market, gender): dates = self.bn_date_picker.text.replace(" ", "").split("–") start_date = datetime.datetime.strptime(dates[0], "%m/%d/%y").strftime("%Y-%m-%d") end_date = datetime.datetime.strptime(dates[1], "%m/%d/%y").strftime("%Y-%m-%d") resp = self.api.dsp.get_apple_demographics_delphi(isrc, start_date, end_date, market)["body"][0]["age_bands"] self.log.info(resp) age_18_24 = DataFormatter.round_streams_demographics(resp[f"{gender}_18_24"]).upper() age_25_34 = DataFormatter.round_streams_demographics(resp[f"{gender}_25_34"]).upper() age_35_44 = DataFormatter.round_streams_demographics(resp[f"{gender}_35_44"]).upper() age_45_54 = DataFormatter.round_streams_demographics(resp[f"{gender}_45_54"]).upper() age_55_64 = DataFormatter.round_streams_demographics(resp[f"{gender}_55_64"]).upper() age_65 = DataFormatter.round_streams_demographics(resp[f"{gender}_65_plus"]).upper() age_unkn = DataFormatter.round_streams_demographics(resp[f"{gender}_unknown"]).upper() return age_18_24, age_25_34, age_35_44, age_45_54, age_55_64, age_65, age_unkn @allure.step("Getting streams monitoring data for from api") def get_streams_monitoring_api(self, isrc, market): dates = self.bn_date_picker.text.replace(" ", "").split("–") start_date = datetime.datetime.strptime(dates[0], "%m/%d/%y").strftime("%Y-%m-%d") end_date = datetime.datetime.strptime(dates[1], "%m/%d/%y").strftime("%Y-%m-%d") resp = self.api.dsp.get_dsp_api_streams_monitoring(isrc, f"start_date={start_date}", f"end_date={end_date}", market)["body"] self.log.info(resp) spotify = [ DataFormatter.round_streams_demographics(resp["spotify"]["lean_back"]), DataFormatter.round_streams_demographics(resp["spotify"]["lean_forward"]), ] apple = [ DataFormatter.round_streams_demographics(resp["apple"]["lean_back"]), DataFormatter.round_streams_demographics(resp["apple"]["lean_forward"]), ] amazon = [ DataFormatter.round_streams_demographics(resp["amazon"]["lean_back"]), DataFormatter.round_streams_demographics(resp["amazon"]["lean_forward"]), ] self.log.info(spotify) self.log.info(apple) self.log.info(amazon) return spotify, apple, amazon @allure.step("Getting streams monitoring data for from api without rounding") def get_streams_monitoring_count_no_rounding(self, isrc, market): dates = self.bn_date_picker.text.replace(" ", "").split("–") start_date = datetime.datetime.strptime(dates[0], "%m/%d/%y").strftime("%Y-%m-%d") end_date = datetime.datetime.strptime(dates[1], "%m/%d/%y").strftime("%Y-%m-%d") resp = self.api.dsp.get_dsp_api_streams_monitoring(isrc, f"start_date={start_date}", f"end_date={end_date}", market)["body"] self.log.info(resp) spotify = [resp["spotify"]["lean_back"], resp["spotify"]["lean_forward"]] apple = [resp["apple"]["lean_back"], resp["apple"]["lean_forward"]] amazon = [resp["amazon"]["lean_back"], resp["amazon"]["lean_forward"]] self.log.info(spotify) self.log.info(apple) self.log.info(amazon) return spotify, apple, amazon @allure.step("Getting percentage from age demographcs cards") def get_card_age_demographics_cards_percentage(self): self.lb_demographics_age_block_1.wait(to_assert=False) self.lb_demographics_age_block_2.wait(to_assert=False) data_1 = self.lb_demographics_age_block_1.text.replace("%", "").replace("~", "").split() data_2 = self.lb_demographics_age_block_2.text.replace("%", "").replace("~", "").split() data = data_1[2::3] + data_2[2::3] data_sum = [int(i) for i in data] self.log.info(sum(data_sum)) return sum(data_sum) @allure.step("Getting streams from age demographcs cards") def get_card_age_demographics_cards_streams(self): data_1 = self.lb_demographics_age_block_1.text.split() data_2 = self.lb_demographics_age_block_2.text.split() data = data_1[1::3] + data_2[1::3] self.log.info(data) return data @allure.step("Getting data from gender demographics tile") def get_demographics_gender_tile_data(self): return self.lb_demographics_tile_content.visible_text @allure.step("Getting data from spotify chart widget card") def get_spotify_widget_data(self): return self.bn_charts_spotify.text @allure.step("Getting data from apple chart widget card") def get_apple_widget_data(self): return self.bn_charts_apple.text @allure.step("Getting charts number form chart widget data") def get_chats_count_from_chart_widget(self, widget_data): chart_number = widget_data.partition("Chart")[0].split()[-1] self.log.info(f"Get charts number from widget data: {chart_number}") return chart_number @allure.step("Getting data from Streams Monitoring card") def get_streams_monitoring_data(self): return self.lb_streams_monitoring_card.visible_text @allure.step("Getting data from Streams Monitoring card") def get_date_picker_button(self): return self.bn_date_picker_button.visible_text @allure.step("Getting data on demographics gender tile") def get_audience_demographics_tile_1(self): wait(self.bn_demographic_tile_1.is_present) return self.bn_demographic_tile_1.text @allure.step("Getting data on demographics gender tile") def get_audience_demographics_tile_2(self): wait(self.bn_demographic_tile_2.is_present) return self.bn_demographic_tile_2.text @allure.step("Getting data on demographics gender tile") def get_audience_demographics_tile_4(self): wait(self.bn_demographic_tile_4.is_present) return self.bn_demographic_tile_4.text @allure.step("Getting data on demographics gender tile") def get_audience_demographics_tile_3(self): wait(self.bn_demographic_tile_3.is_present) return self.bn_demographic_tile_3.text @allure.step("Getting dates from by age statistic section") def get_dates_by_age(self): return self.lb_by_age_data.visible_text @allure.step("Verifying lean back and lean forward calculation") def are_lean_back_and_forward_values_100_by_dsp(self): apple, amazon, spotify = self.lb_apple_value.label, self.lb_amazon_value.label, self.lb_spotify_value.label apple, amazon, spotify = map(lambda x: x.strip("()").replace("%", "").replace("~", ""), (apple, amazon, spotify)) return int(apple) + int(amazon) + int(spotify) == 100 @allure.step("Verifying market selector available on main track screen for global market") def is_market_selection_card_displayed(self): return self.bn_select_market.is_present() @allure.step("Verifying DSP Latency section is displayed") def is_dsp_latency_global_displayed(self): return self.lb_dsp_latency_title.is_visible() and self.lb_dsp_global_lines.is_visible() @allure.step("Verifying DSP Latency section is displayed") def is_market_details_dsp_latency_global_displayed(self): return self.lb_dsp_latency_global_title.is_visible() @allure.step("Verifying DSP Latency section is displayed") def is_market_details_dsp_latency_market_displayed(self, market, dates): locator = '//XCUIElementTypeOther[@label="{} DSP Latency"]/following-sibling::XCUIElementTypeOther[\'{} ' "\uEA87 \uE91F \uE91E']".format(market, dates) return self.is_element_displayed(locator, "xpath") @allure.step("Verifying DSP Latency section is NOT displayed") def no_market_details_dsp_latency_market_displayed(self): locator = '**/XCUIElementTypeOther[`label CONTAINS "DSP Latency"`]' return not self.is_element_displayed(locator, "class-chain") @allure.step("Verifying DSP Latency section is NOT displayed") def no_dsp_latency_global_displayed(self): return not self.lb_dsp_latency_title.is_visible() and not self.lb_dsp_global_lines.is_visible() @allure.step("Verifying DSP Latency section for selected market is displayed") def is_dsp_latency_market_displayed(self, market, dates): locator = "//XCUIElementTypeStaticText[@label='{}']/following-sibling::XCUIElementTypeOther[contains(@label,'{}" "   ')]".format(market, dates) return self.is_element_displayed(locator, "xpath") @allure.step("Verifying DSP Latency section for selected market is NOT displayed") def no_dsp_latency_market_displayed(self, market): locator = "//XCUIElementTypeStaticText[@label='{}']/following-sibling::XCUIElementTypeOther[contains(@label," "'  ')]".format(market) return not self.is_element_displayed(locator, "xpath") @allure.step("Verifying DSP Latency dates are valid") def are_dsp_latency_dates_matching(self, dates): locator = "//XCUIElementTypeStaticText[@label=\"Global\"]/following-sibling::XCUIElementTypeOther['{}   ']".format(dates) return self.is_element_displayed(locator, "xpath") @allure.step("Verifying DSP Latency dates are valid") def are_market_dsp_latency_dates_matching(self, dates): locator = '//XCUIElementTypeOther[@label="Global DSP Latency"]/following-sibling::XCUIElementTypeOther[\'{}' "   ']".format(dates) return self.is_element_displayed(locator, "xpath") @allure.step("Verifying top 5 markets Show All button is displayed") def is_top_5_show_all_displayed(self): return self.bn_top_markets_show_all.is_visible() @allure.step("Verifying top 5 markets Show All button is NOT displayed") def is_top_5_show_all_not_displayed(self): return not self.bn_top_markets_show_all.is_visible() @allure.step("Verifying streams monitoring section is displayed") def is_streams_monitoring_shown(self): self.scroll_to_streams_monitoring() return self.bn_streams_monitoring_spotify.is_present() and self.lb_lean_forward_value.is_present() @allure.step("Verifying NO demographics available for all vendors") def is_no_demographics_available_for_all_vendors(self): self.lb_no_demographics_all.wait(to_assert=False) return self.lb_no_demographics_all.is_present() @allure.step("Verifying demographics popup is opened") def is_demographics_popup_opened(self): self.lb_demographics_popup_heading.wait(to_assert=False) return self.lb_demographics_popup_heading.is_present() @allure.step("Verifying demographics popup is closed") def is_demographics_popup_closed(self): return not self.lb_demographics_popup_heading.is_present() @allure.step("Verifying demographics section is available") def is_audience_demographics_dispalyed(self): self.lb_by_gender_demographics_title.wait(to_assert=False) return self.lb_by_gender_demographics_title.is_present() @allure.step("Verifying no demographics data for apple is available") def no_apple_demographics_data(self): self.lb_no_apple_demographics.wait(to_assert=False) return self.lb_no_apple_demographics.is_present() @allure.step("Verifying demographics tiles size") def are_demographics_tiles_equal(self): male_tile_size = self.bn_demographic_tile_1.size female_tile_size = self.bn_demographic_tile_2.size return male_tile_size == female_tile_size @allure.step("Verifying demographics tiles size") def are_demographics_tiles_not_equal(self): male_tile_size = self.bn_demographic_tile_1.size female_tile_size = self.bn_demographic_tile_2.size return male_tile_size != female_tile_size @allure.step("Verifying demographics popup content") def is_spotify_popup_content_displayed(self): dates = self.bn_date_picker.text.replace(" ", "") locator = "//XCUIElementTypeOther[contains(@label, '{}') and contains(@label, '60+') and " "contains(@label, '0–17')]".format(dates) return self.is_element_displayed(locator, "xpath") @allure.step("Verifying demographics popup content") def is_apple_popup_content_displayed(self): dates = self.bn_date_picker.text.replace(" ", "") locator = "//XCUIElementTypeOther[contains(@label, '{}') and contains(@label, '65+') and " "contains(@label, '18–24')]".format(dates) return self.is_element_displayed(locator, "xpath") @allure.step("Verifying top age tile present") def is_demographics_top_age_tile_present(self): self.lb_by_gender_demographics_title.wait(to_assert=True) blocks = self.lt_demographics_age_blocks.elements return len(blocks) == 3 @allure.step("Verifying top age tile NOT present") def is_demographics_top_age_tile_not_present(self): self.lb_by_gender_demographics_title.wait(to_assert=False) blocks = self.lt_demographics_age_blocks.elements return len(blocks) == 2 @allure.step("Verifying the proper track page is opened") def is_track_page_opened(self, track_name): self.lb_global_streams.wait(to_assert=False) track_title_locator = '**/XCUIElementTypeOther[`label CONTAINS[c] "{}"`][-1]'.format(track_name) element = self.get_element(track_title_locator, "class-chain") return element is not None @allure.step("Verifying that there is no youtube and tiktok data available") def is_youtube_and_tiktok_videos_not_available(self): return self.lb_no_youtube_and_tiktok_videos_available_text.is_visible() @allure.step("Verifying user is redirected to web browser") def is_spotify_partner_page_is_opened_in_browser(self, track): track_locator = '**/XCUIElementTypeStaticText[`label =="{}"`]'.format(track) address_locator = "//XCUIElementTypeButton[contains (@value, 'open.spotify.com')]" self.wait_for_element_visible(track_locator, "class-chain") return self.is_element_displayed(address_locator, "xpath") and self.is_element_displayed(track_locator, "class-chain") @allure.step("Verifying user is redirected to web browser") def is_apple_partner_page_is_opened_in_browser(self, track): address_locator = "//XCUIElementTypeButton[contains (@value, 'music.apple.com')]" self.wait_for_element_visible(address_locator, "xpath") return self.is_element_displayed(address_locator, "xpath") @allure.step("Verifying track data is changed accordingly to the market") def is_no_stream_data_for_market(self, market): locator = f"**/XCUIElementTypeOther[`label CONTAINS 'No streams available\\nin {market}')`]" return self.is_element_displayed(locator, "class-chain") @allure.step("Verifying detailed view is opened") def is_detailed_streams_overview_opened(self): self.bn_close_detailed_view.wait(to_assert=False) orientation = self.driver.orientation return orientation == "LANDSCAPE" and self.lb_combined_streams_legend.is_visible() @allure.step("Verifying detailed view is opened for small markets") def is_detailed_streams_overview_opened_small_markets(self): self.bn_close_detailed_view.wait(to_assert=False) orientation = self.driver.orientation if orientation == "LANDSCAPE": return True @allure.step("Verifying detailed view is opened") def is_dsp_detailed_streams_overview_opened(self): self.bn_close_detailed_view.wait(to_assert=False) orientation = self.driver.orientation return orientation == "LANDSCAPE" and self.lb_dsp_streams_legend.is_visible() @allure.step("Verifying detailed view is closed") def is_detailed_streams_overview_closed(self): self.bn_global_market_card.wait(to_assert=False) return self.driver.orientation == "PORTRAIT" @allure.step("Verifying detailed view is closed (Spotify/Amazon/Apple)") def is_detailed_streams_overview_closed_per_vendor(self): self.bn_global_market_card.wait(to_assert=False) return self.driver.orientation == "PORTRAIT" @allure.step("Verifying info popup is opened") def is_markets_popup_opened(self): self.lb_markets_popup_text.wait(to_assert=False) self.lb_markets_popup_text_2.wait(to_assert=False) self.lb_markets_popup_text_3.wait(to_assert=False) self.lb_markets_popup_text_4.wait(to_assert=False) return self.lb_markets_popup_text.is_visible() and self.lb_markets_popup_text_2.is_visible() and self.lb_markets_popup_text_3.is_visible() and self.lb_markets_popup_text_4.is_visible() @allure.step("Verifying info popup is opened") def is_charts_placements_popup_opened(self): self.lb_charts_placements_popup_text.wait(to_assert=False) self.lb_charts_placements_popup_text_1.wait(to_assert=False) return self.lb_charts_placements_popup_text.is_visible() and self.lb_charts_placements_popup_text_1.is_visible() @allure.step("Verifying info popup is opened") def is_streams_overview_popup_opened(self): self.lb_streams_overview_popup_text.wait(to_assert=False) self.lb_streams_overview_popup_text_1.wait(to_assert=False) return self.lb_streams_overview_popup_text.is_visible() and self.lb_streams_overview_popup_text_1.is_visible() @allure.step("Verifying info popup is opened") def is_audience_popup_opened(self): self.lb_audience_popup_text.wait(to_assert=False) self.lb_audience_popup_text_1.wait(to_assert=False) self.lb_audience_popup_text_2.wait(to_assert=False) self.lb_audience_popup_text_3.wait(to_assert=False) return self.lb_audience_popup_text.is_visible() and self.lb_audience_popup_text_1.is_visible() and self.lb_audience_popup_text_2.is_visible() and self.lb_audience_popup_text_3.is_visible() @allure.step("Verifying info popup is opened") def is_strams_monitoring_popup_opened(self): self.lb_streams_monitoring_popup_text.wait(to_assert=False) self.lb_streams_monitoring_popup_text_1.wait(to_assert=False) self.lb_streams_monitoring_popup_text_2.wait(to_assert=False) self.lb_streams_monitoring_popup_text_3.wait(to_assert=False) return self.lb_streams_monitoring_popup_text.is_visible() and self.lb_streams_monitoring_popup_text_1.is_visible() and self.lb_streams_monitoring_popup_text_2.is_visible() and self.lb_streams_monitoring_popup_text_2.is_visible() @allure.step("Verifying track image is displayed") def is_track_image_displayed(self): return wait(self.lb_track_image.is_present) @allure.step("Verifying track image area is displayed") def is_track_page_top_section_displayed(self): self.lb_track_title_area.wait(to_assert=False) return self.lb_track_title_area.is_visible() @allure.step("Verifying spotify charts unavailable for spotify track") def is_spotify_charts_unavailable(self): self.scroll_to_chart_placements() return self.lb_spotify_unavailable.is_present() @allure.step("Verifying apple charts unavailable for apple track") def is_apple_charts_unavailable(self): self.scroll_to_chart_placements() return self.lb_apple_unavailable.is_present() @allure.step("Checking market on the track page") def is_market_selected(self, market_code, country): locator = "**/XCUIElementTypeOther[`label CONTAINS '{} '`]".format(market_code) locator_streams = "**/XCUIElementTypeOther[`label CONTAINS '{} Streams'`]".format(market_code) message = "**/XCUIElementTypeStaticText[`label CONTAINS '{} or Global markets'`]".format(market_code) message_unavilable = '**/XCUIElementTypeOther[`label CONTAINS "No streams available \\n for {}."`]'.format(market_code) if self.is_element_displayed(locator, "class-chain") or self.is_element_displayed(locator_streams, "class-chain") or self.is_element_displayed(message, "class-chain") or self.is_element_present(message_unavilable, "class-chain"): return True @allure.step("Verifying markets section availability") def is_markets_section_available_without_data_global(self): self.lb_markets_title.wait(to_assert=False) return self.lb_markets_title.is_visible() and self.lb_markets_global_unavailable.is_visible() @allure.step("Verifying markets section availability") def is_markets_section_available_with_data(self): self.lb_markets_title.wait(to_assert=False) return self.lb_markets_title.is_visible() and self.bn_global_market_card.is_visible() and self.lb_us_card.is_visible() @allure.step("Verifying markets section availability") def is_markets_section_available_with_data_market(self): self.lb_markets_title.wait(to_assert=False) return self.lb_markets_title.is_visible() and self.lb_markets_us_unavailable.is_visible() @allure.step("Verifying market selector in case of wrong name of the market") def is_market_section_available_without_correct_data(self): return self.lb_no_charts_search_results_msg.is_visible() @allure.step("Verifying charts placements section availability") def is_charts_section_available_without_data(self): return self.lb_empty_charts.is_visible() @allure.step("Verifying 1 year filter applied") def is_1_year_date_filter_applied(self, dates): self.bn_date_picker_2_weeks.wait(to_assert=False) card_dates = self.lb_combined_streams_card.label monitoring_dates = self.lb_streams_monitoring_sircle_date.label date = dates["1 year"] formatted_date = date.split("–") self.log.info((formatted_date)[0] + " " + (formatted_date)[1] + " " + date) self.log.info(card_dates + " " + monitoring_dates) return (formatted_date)[0] in card_dates and (formatted_date)[1] in card_dates and date in monitoring_dates @allure.step("Verifying 2 weeks filter applied") def is_2_weeks_date_filter_applied(self, dates): self.bn_date_picker_2_weeks.wait(to_assert=False) self.lb_streams_monitoring_sircle_date.wait(to_assert=False) card_dates = self.lb_combined_streams_card.label monitoring_dates = self.lb_streams_monitoring_sircle_date.label date = dates["2 weeks"] formatted_date = date.split("–") self.log.info((formatted_date)[0] + " " + (formatted_date)[1] + " " + date) self.log.info(card_dates + " " + monitoring_dates) return (formatted_date)[0] in card_dates and (formatted_date)[1] in card_dates and date in monitoring_dates @allure.step("Verifying 4 weeks filter applied") def is_4_weeks_date_filter_applied(self, dates): self.bn_date_picker_2_weeks.wait(to_assert=False) self.lb_streams_monitoring_sircle_date.wait(to_assert=False) card_dates = self.lb_combined_streams_card.label monitoring_dates = self.lb_streams_monitoring_sircle_date.label date = dates["4 weeks"] formatted_date = date.split("–") self.log.info((formatted_date)[0] + " " + (formatted_date)[1] + " " + date) self.log.info(card_dates + " " + monitoring_dates) return (formatted_date)[0] in card_dates and (formatted_date)[1] in card_dates and date in monitoring_dates @allure.step("Verifying 8 weeks filter applied") def is_8_weeks_date_filter_applied(self, dates): wait(lambda: self.bn_date_picker_2_weeks.is_visible() is False) self.lb_streams_monitoring_sircle_date.wait(to_assert=False) card_dates = self.lb_combined_streams_card.label monitoring_dates = self.lb_streams_monitoring_sircle_date.label date = dates["8 weeks"] formatted_date = date.split("–") self.log.info((formatted_date)[0] + " " + (formatted_date)[1] + " " + date) self.log.info(card_dates + " " + monitoring_dates) return (formatted_date)[0] in card_dates and (formatted_date)[1] in card_dates and date in monitoring_dates @allure.step("Verifying 12 weeks filter applied") def is_12_weeks_date_filter_applied(self, dates): self.bn_date_picker_2_weeks.wait(to_assert=False) self.lb_streams_monitoring_sircle_date.wait(to_assert=False) card_dates = self.lb_combined_streams_card.label monitoring_dates = self.lb_streams_monitoring_sircle_date.label date = dates["12 weeks"] formatted_date = date.split("–") self.log.info((formatted_date)[0] + " " + (formatted_date)[1] + " " + date) self.log.info(card_dates + " " + monitoring_dates) return (formatted_date)[0] in card_dates and (formatted_date)[1] in card_dates and date in monitoring_dates @allure.step("Verifying 26 weeks filter applied") def is_26_weeks_date_filter_applied(self, dates): self.bn_date_picker_2_weeks.wait(to_assert=False) self.lb_streams_monitoring_sircle_date.wait(to_assert=False) card_dates = self.lb_combined_streams_card.label monitoring_dates = self.lb_streams_monitoring_sircle_date.label date = dates["26 weeks"] formatted_date = date.split("–") self.log.info((formatted_date)[0] + " " + (formatted_date)[1] + " " + date) self.log.info(card_dates + " " + monitoring_dates) return (formatted_date)[0] in card_dates and (formatted_date)[1] in card_dates and date in monitoring_dates @allure.step("Verifying charts placements section availability") def is_charts_section_available_with_data(self): visibility_of_section = self.lb_charts_title.is_visible() and self.bn_charts_spotify.is_visible() and self.bn_charts_apple.is_visible() return visibility_of_section @allure.step("Verifying date picker is opened") def is_date_picker_opened(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 market selector is opened") def is_market_selector_opened(self): self.bn_markets_done.is_visible() return self.bn_markets_done.is_visible() & self.bn_markets_cancel.is_visible() @allure.step("Clicking cancel button on market search screen") def click_market_search_cancel_button(self): self.bn_markets_cancel.click() return self @allure.step("Verifying market is changed") def is_market_changed(self, market): selector_locator = "**/XCUIElementTypeOther[`label CONTAINS '{} Streams'`]".format(market) self.wait_for_element_visible(selector_locator, "class-chain") return self.is_element_displayed(selector_locator, "class-chain", None) @allure.step("Verifying streams overview cards are displayed") def are_streams_overview_graphs_shown(self): return self.lb_combined_streams_card.is_visible() and self.lb_spotify_streams_count.is_visible() and self.lb_apple_streams_count.is_present() and self.lb_amazon_streams_count.is_present() @allure.step("Verifying one of streams overview cards is displayed") def are_one_of_streams_overview_graphs_shown(self): return self.lb_combined_streams_card.is_visible() or self.lb_spotify_streams_count.is_visible() or self.lb_apple_streams_count.is_visible() or self.lb_amazon_streams_count.is_visible() @allure.step("Verifying playlists popup is opened") def is_playlists_info_popup_opened(self): return self.lb_playlists_popup_text.is_present() and self.lb_playlists_popup_title.is_present() @allure.step("Verifying latest adds popup is opened") def is_latest_adds_info_popup_opened(self): return self.lb_latest_adds_popup_text.is_present() and self.lb_latest_adds_popup_title.is_present() @allure.step("Verifying latest removals popup is opened") def is_latest_removals_info_popup_opened(self): return self.lb_latest_removals_i_popup_title.is_present() and self.lb_latest_removals_i_popup_text.is_present() @allure.step("Verifying top 5 popup is opened") def is_top_5_playlists_popup_opened(self): return self.lb_top_5_popup_text.is_present() @allure.step("Verifying streams overview cards are not displayed for particular dsp") def no_streams_overview_graphs_for_dsp(self): self.lb_no_streams_dsp.wait(to_assert=False) return self.lb_no_streams_dsp.is_present() @allure.step("Verifying streams overview cards are not displayed for all dsps") def no_streams_overview_graphs(self): self.lb_no_streams_all.wait(to_assert=False) return self.lb_no_streams_all.is_visible() @allure.step("Verifying that Apple streams monitoring card is empty") def no_apple_streams_displayed(self): self.lb_no_streams_apple.wait(to_assert=False) return self.lb_no_streams_apple.is_visible() @allure.step("Verifying the passed search value is in the results list") def is_search_value_in_list(self, value, results): passed = True value_formatted = value.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 @allure.step("Verifying spotify playlists empty states are displayed") def are_spotify_playlists_empty_states_displayed(self): return self.lb_no_spotify_playlists_msg.is_present() and self.lb_no_spotify_latest_adds_msg.is_present() and self.lb_no_spotify_top_5_msg.is_present() @allure.step("Verifying apple playlists empty states are displayed") def are_apple_playlists_empty_states_displayed(self): return self.lb_no_apple_playlists_msg.is_present() and self.lb_no_apple_latest_adds_msg.is_present() and self.lb_no_apple_top_5_msg.is_present() @allure.step("Verifying amazon playlists empty states are displayed") def are_amazon_playlists_empty_states_displayed(self): return self.lb_no_apple_playlists_msg.is_present() and self.lb_no_apple_latest_adds_msg.is_present() and self.lb_no_apple_top_5_msg.is_present() @allure.step("Verifying latest adds section is not empty") def is_lastes_adds_contains_playlists(self): return not self.lb_no_spotify_latest_adds_msg.is_present() @allure.step("Verifying top 5 section is not empty") def is_top_5_contains_playlists(self): return not self.lb_no_apple_top_5_msg.is_present() @allure.step("Verifying charts search is empty") def is_charts_search_empty(self): query = self.in_charts_search.visible_text return len(query) == 0 @allure.step("Verifying no search results message is displayed") def is_no_charts_search_results_msg_shown(self): return self.lb_no_charts_search_results_msg.is_present() @allure.step("Verifying on strea,s available for selected period on market details page") def is_no_streams_for_period_on_market_details(self): return self.lb_no_stremas_streams_overview.is_present() and self.lb_no_stremas_demographics.is_present() and self.lb_no_stremas_monitoring.is_present() @allure.step("Verifying track is unavailable message is displayed") def is_track_unavailable_error_is_displayed(self): return self.lb_track_is_unavailable.is_visible() @allure.step("Verifying Filtered Playlists has correct information") def is_filtered_playlists_widget_has_correct_information(self, current, vendor, past=None, total=None): if vendor == "Spotify" or vendor == "Apple": widget_locator = f'**/XCUIElementTypeOther[`label == "Filtered Playlists  {current:,} Current {total:,} Total {past:,} Past"`][2]' elif vendor == "Amazon": widget_locator = f'**/XCUIElementTypeOther[`label == "Filtered Playlists  {current:,} Current"`][2]' self.wait_for_element_visible(widget_locator, "class-chain") return self.is_element_displayed(widget_locator, "class-chain")