from appium.webdriver.common.appiumby import AppiumBy from selenium.common.exceptions import TimeoutException from selenium.webdriver.common.by import By from helpers.platform.ios.locators import ( ios_label_equals, ios_other_by_name, ios_static_text_by_name) from ..base_screen import BaseScreen from ..mixins.utils import retry_on_assertion class SearchScreen(BaseScreen): fresh_keyboard = True first_search = True search_bar = '//XCUIElementTypeTextField[@name="searchBar"]' loader = 'viewLoader' recent_searches_title = ios_label_equals('Recent Searches') artists_header = ('**/XCUIElementTypeOther' '[`label CONTAINS "search.results.artistsheader"`]') artist_component = 'participantComponent' song_component = 'topTracksItem' product_component = 'product' keyboard_cont = 'Continue' close_keyboard = 'Search' cancel_button = 'cancelButton' clear_button = 'clearButton' clear_recent_results_btn = ios_other_by_name('clearRecentResults') no_recent_results_placeholder = ios_static_text_by_name( 'Search for Songs, products, or any artist') def __init__(self, driver, browserstack): super().__init__(driver) self.browserstack = browserstack def search(self, item, wait_for_results): def search_for_item(): if not self.first_search: self.waiter(10, By.ID, self.cancel_button).click() self.waiter(10, By.XPATH, self.search_bar).send_keys(item) self.first_search = False if self.fresh_keyboard: self.driver.hide_keyboard(self.close_keyboard) self.fresh_keyboard = False self.waiter(60, AppiumBy.IOS_CLASS_CHAIN, self.artists_header) try: search_for_item() except TimeoutException: self.driver.find_element(By.ID, self.cancel_button).click() search_for_item() @retry_on_assertion() def assert_product(self, product_id): self.waiter(10, AppiumBy.IOS_PREDICATE, 'name CONTAINS "product"') id_string = f'product{product_id}' self.scroll_and_assert(By.ID, id_string, max_scrolls=10, small_scroll=True) def get_artist_id(self, artist, artist_id): return f'{self.artist_component}-{artist}-{artist_id}' def get_song_id(self, song, song_id): return f'{self.song_component}{song_id}' def get_product_id(self, product_id): return f'{self.product_component}{product_id}' def assert_artist(self, artist, artist_id): id_string = self.get_artist_id(artist, artist_id) self.scroll_and_assert(By.ID, id_string) def assert_song(self, song, song_id): id_string = self.get_song_id(song, song_id) self.scroll_and_assert(By.ID, id_string, small_scroll=True) def assert_artist_in_recent_search(self, artist, artist_id): self.waiter(5, AppiumBy.IOS_CLASS_CHAIN, self.recent_searches_title) id_string = self.get_artist_id(artist, artist_id) self.scroll_and_assert(By.ID, id_string) def assert_song_in_recent_search(self, song, song_id): self.waiter(5, AppiumBy.IOS_CLASS_CHAIN, self.recent_searches_title) id_string = self.get_song_id(song, song_id) self.scroll_and_assert(By.ID, id_string) def assert_product_in_recent_search(self, product_id): self.waiter(5, AppiumBy.IOS_CLASS_CHAIN, self.recent_searches_title) id_string = self.get_product_id(product_id) self.scroll_and_assert(By.ID, id_string) def tap_product(self, product_id): id_string = f'product{product_id}' self.waiter(10, By.ID, id_string).click() def tap_artist(self, artist, artist_id): id_string = self.get_artist_id(artist, artist_id) self.driver.find_elements(By.ID, id_string)[0].click() def tap_song(self, song, song_id): loc = f'(//XCUIElementTypeOther[@name="topTracksItem{song_id}"])[2]' self.driver.find_elements(By.XPATH, loc)[0].click() def clear_search_field(self): self.driver.find_element(By.ID, self.clear_button).click() def clear_recent_results(self): self.scroll_and_assert(AppiumBy.IOS_CLASS_CHAIN, self.clear_recent_results_btn) self.waiter(3, AppiumBy.IOS_CLASS_CHAIN, self.clear_recent_results_btn).click() def verify_no_recent_results_visible(self): try: self.waiter(10, AppiumBy.IOS_CLASS_CHAIN, self.no_recent_results_placeholder) except TimeoutException: raise AssertionError('Recent results are still visible.') def verify_recent_search_on_line_ios( self, entry_line, search_item, identifier): xpath = \ (f'(//XCUIElementTypeOther[@name="Recent Searches"]/' f'following-sibling::XCUIElementTypeOther)[{entry_line}]') elem = self.waiter(10, By.XPATH, xpath) element_name = elem.get_attribute('name') assert identifier in element_name, ( f"Assertion failed for recent search entry on line {entry_line}. " f"Expected item '{search_item}' with ID '{identifier}', " f"but found element with name '{element_name}'." )