def test_rtd_search_remove_from_url_when_modal_closed(selenium, app, status, warning): """Test if `rtd_search` query param is removed when the modal is closed.""" app.build() path = app.outdir / 'index.html' # to test this, we need to override the $.ajax function ajax_func = get_ajax_overwrite_func('error') injected_script = SCRIPT_TAG + ajax_func with InjectJsManager(path, injected_script) as _: selenium.get(f'file://{path}?rtd_search=i am searching') time.sleep(3) # give time to open modal and start searching # closing modal search_outer = selenium.find_element_by_class_name('search__outer') search_outer_wrapper = selenium.find_element_by_class_name( 'search__outer__wrapper') actions = webdriver.common.action_chains.ActionChains(selenium) actions.move_to_element_with_offset( search_outer, -10, -10 # -ve offsets to move the mouse away from the search modal ) actions.click() actions.perform() WebDriverWait(selenium, 10).until( EC.invisibility_of_element(search_outer_wrapper)) assert (search_outer_wrapper.is_displayed() is False ), 'search modal should disappear after clicking on backdrop' assert ( 'rtd_search=' not in parse.unquote(selenium.current_url) ), 'rtd_search url param should not be present in the url when the modal is closed.'
def test_enter_button_on_input_field_when_no_result_active( selenium, app, status, warning): """ Test if pressing Enter on search field takes the user to search page. User will be redirected to the search page only if no result is active. A search result becomes active if the user reaches to it via ArrowUp and ArrowDown buttons. """ app.build() path = app.outdir / 'index.html' # to test this, we need to override the $.ajax function ajax_func = get_ajax_overwrite_func('error') injected_script = SCRIPT_TAG + ajax_func with InjectJsManager(path, injected_script) as _: selenium.get(f'file://{path}') open_search_modal(selenium) search_outer_input = selenium.find_element_by_class_name( 'search__outer__input') search_outer_input.send_keys('i am searching') search_outer_input.send_keys(Keys.ENTER) WebDriverWait(selenium, 10).until(EC.url_contains(app.outdir / 'search.html')) # enter button should redirect the user to search page assert ('search.html' in selenium.current_url ), 'search.html must be in the url of the page' assert ('Search' in selenium.title), '"Search" must be in the title of the page'
def test_modal_open_if_rtd_search_is_present(selenium, app, status, warning): """Test if search modal opens if `rtd_search` query param is present in the URL.""" app.build() path = app.outdir / 'index.html' # to test this, we need to override the $.ajax function ajax_func = get_ajax_overwrite_func('error') injected_script = SCRIPT_TAG + ajax_func with InjectJsManager(path, injected_script) as _: selenium.get(f'file://{path}?rtd_search=i am searching') time.sleep(3) # give time to open modal and start searching search_outer_wrapper = selenium.find_element_by_class_name( 'search__outer__wrapper') search_result_box = selenium.find_element_by_class_name( 'search__result__box') assert (search_outer_wrapper.is_displayed() is True), 'search modal should displayed when the page loads' assert ( search_result_box.text == 'Error Occurred. Please try again.' ), 'user should be notified that there is error while searching' assert ( len(search_result_box.find_elements_by_css_selector('*')) == 0 ), 'search result box should not have any child elements because there are no results'
def test_searching_msg(selenium, app, status, warning): """Test if the user is notified that search is in progress.""" app.build() path = app.outdir / 'index.html' # to test this, we need to override the $.ajax function ajax_func = get_ajax_overwrite_func('timeout__zero_results') injected_script = SCRIPT_TAG + ajax_func with InjectJsManager(path, injected_script) as _: selenium.get(f'file://{path}') open_search_modal(selenium) search_outer_input = selenium.find_element_by_class_name( 'search__outer__input') search_outer_input.send_keys('searching the results') search_result_box = selenium.find_element_by_class_name( 'search__result__box') assert (search_result_box.text == 'Searching ....' ), 'user should be notified that search is in progress' WebDriverWait(selenium, 10).until( EC.text_to_be_present_in_element( (By.CLASS_NAME, 'search__result__box'), 'No Results Found')) # fetching it again from the DOM to update its status search_result_box = selenium.find_element_by_class_name( 'search__result__box') assert ( len(search_result_box.find_elements_by_css_selector('*')) == 0 ), 'search result box should not have any child elements because there are no results' assert (search_result_box.text == 'No Results Found' ), 'user should be notified that there are no results'
def test_error_msg(selenium, app, status, warning): """Test if the user is notified that there is an error while performing search""" app.build() path = app.outdir / 'index.html' # to test this, we need to override the $.ajax function ajax_func = get_ajax_overwrite_func('error') injected_script = SCRIPT_TAG + ajax_func with InjectJsManager(path, injected_script) as _: selenium.get(f'file://{path}') open_search_modal(selenium) search_outer_input = selenium.find_element_by_class_name( 'search__outer__input') search_outer_input.send_keys('this will result in error') WebDriverWait(selenium, 10).until( EC.text_to_be_present_in_element( (By.CLASS_NAME, 'search__result__box'), 'Error Occurred. Please try again.')) search_result_box = selenium.find_element_by_class_name( 'search__result__box') assert (search_result_box.text == 'Error Occurred. Please try again.' ), 'user should be notified that there is an error' assert ( len(search_result_box.find_elements_by_css_selector('*')) == 0 ), 'search result box should not have any child elements because there are no results'
def test_writing_query_adds_rtd_search_as_url_param(selenium, app, status, warning): """Test if the `rtd_search` query param is added to the url when user is searching.""" app.build() path = app.outdir / 'index.html' # to test this, we need to override the $.ajax function ajax_func = get_ajax_overwrite_func('error') injected_script = SCRIPT_TAG + ajax_func with InjectJsManager(path, injected_script) as _: selenium.get(f'file://{path}') open_search_modal(selenium) query = 'searching' query_len = len(query) assert ( 'rtd_search=' not in parse.unquote(selenium.current_url) ), 'rtd_search param must not be present in the url when page loads' search_outer_input = selenium.find_element_by_class_name( 'search__outer__input') search_outer_input.send_keys(query) query_param = f'rtd_search={query}' # Wait till it updates the URL time.sleep(0.5) assert (query_param in parse.unquote( selenium.current_url)), 'query param must be present in the url' # deleting query from input field for i in range(query_len): search_outer_input.send_keys(Keys.BACK_SPACE) time.sleep(0.5) if i != query_len - 1: current_query = query[:query_len - i - 1] current_url = parse.unquote(selenium.current_url) query_in_url = current_url[current_url.find('rtd_search'):] assert (f'rtd_search={current_query}' == query_in_url) assert ( 'rtd_search=' not in parse.unquote(selenium.current_url) ), 'rtd_search param must not be present in the url if query is empty'
def test_navigate_results_with_arrow_up_and_down(selenium, app, status, warning): """Test if user is able to navigate through search results via keyboard.""" app.build() path = app.outdir / 'index.html' # to test this, we need to override the $.ajax function ajax_func = get_ajax_overwrite_func('dummy_results') injected_script = SCRIPT_TAG + ajax_func with InjectJsManager(path, injected_script) as _: selenium.get(f'file://{path}') open_search_modal(selenium) search_outer_input = selenium.find_element_by_class_name( 'search__outer__input') search_outer_input.send_keys('sphinx') search_result_box = selenium.find_element_by_class_name( 'search__result__box') WebDriverWait(selenium, 10).until( EC.visibility_of_all_elements_located( (By.CLASS_NAME, 'search__result__single'))) # fetching search_result_box again to update its content search_result_box = selenium.find_element_by_class_name( 'search__result__box') results = selenium.find_elements_by_class_name( 'outer_div_page_results') search_outer_input.send_keys(Keys.DOWN) assert results[0] == selenium.find_element_by_css_selector( '.outer_div_page_results.active'), 'first result should be active' search_outer_input.send_keys(Keys.DOWN) assert results[1] == selenium.find_element_by_css_selector( '.outer_div_page_results.active'), 'second result should be active' search_outer_input.send_keys(Keys.UP) search_outer_input.send_keys(Keys.UP) assert results[-1] == selenium.find_element_by_css_selector( '.outer_div_page_results.active'), 'last result should be active' search_outer_input.send_keys(Keys.DOWN) assert results[0] == selenium.find_element_by_css_selector( '.outer_div_page_results.active'), 'first result should be active'
def test_results_displayed_to_user(selenium, app, status, warning): """Test if the results are displayed correctly to the user.""" app.build() path = app.outdir / 'index.html' # to test this, we need to override the $.ajax function ajax_func = get_ajax_overwrite_func('dummy_results') injected_script = SCRIPT_TAG + ajax_func with InjectJsManager(path, injected_script) as _: selenium.get(f'file://{path}') open_search_modal(selenium) search_outer_input = selenium.find_element_by_class_name( 'search__outer__input') search_outer_input.send_keys('sphinx') search_result_box = selenium.find_element_by_class_name( 'search__result__box') WebDriverWait(selenium, 10).until( EC.visibility_of_all_elements_located( (By.CLASS_NAME, 'search__result__single'))) # fetching search_result_box again to update its content search_result_box = selenium.find_element_by_class_name( 'search__result__box') assert ( len( search_result_box.find_elements_by_class_name( 'search__result__single')) == 1 ), 'search result box should have results from only 1 page (as per the dummy_results.json)' assert ( len( search_result_box.find_elements_by_class_name( 'outer_div_page_results')) == 3 ), 'total 3 results should be shown to the user (as per the dummy_results.json)'