def does_not_autoplay(_step, video_type): world.wait(DELAY) world.wait_for_ajax_complete() actual = world.css_find('.%s' % video_type)[0]['data-autoplay'] expected = [u'False', u'false', False] assert actual in expected assert world.css_has_class('.video_control', 'play')
def set_text_and_select(step, text): script = """ var editor = tinyMCE.activeEditor; editor.setContent(arguments[0]); editor.selection.select(editor.dom.select('p')[0]);""" world.browser.driver.execute_script(script, str(text)) world.wait_for_ajax_complete()
def select_verified_track_upgrade(step): select_contribution(32) world.wait_for_ajax_complete() btn_css = 'input[value="Upgrade Your Registration"]' world.css_click(btn_css) # TODO: might want to change this depending on the changes for upgrade assert world.is_css_present('section.progress')
def does_not_autoplay(_step, video_type): world.wait(DELAY) world.wait_for_ajax_complete() actual = world.css_find(".%s" % video_type)[0]["data-autoplay"] expected = [u"False", u"false", False] assert actual in expected assert world.css_has_class(".video_control", "play")
def press_the_notification_button(_step, name): # TODO: fix up this code. Selenium is not dealing well with css transforms, # as it thinks that the notification and the buttons are always visible # First wait for the notification to pop up notification_css = 'div#page-notification div.wrapper-notification' world.wait_for_visible(notification_css) # You would think that the above would have worked, but it doesn't. # Brute force wait for now. world.wait(.5) # Now make sure the button is there btn_css = 'div#page-notification a.action-%s' % name.lower() world.wait_for_visible(btn_css) # You would think that the above would have worked, but it doesn't. # Brute force wait for now. world.wait(.5) if world.is_firefox(): # This is done to explicitly make the changes save on firefox. # It will remove focus from the previously focused element world.trigger_event(btn_css, event='focus') world.browser.execute_script("$('{}').click()".format(btn_css)) else: world.css_click(btn_css) world.wait_for_ajax_complete()
def edit_component(index=0): # Verify that the "loading" indication has been hidden. world.wait_for_loading() # Verify that the "edit" button is present. world.wait_for(lambda _driver: world.css_visible('a.edit-button')) world.css_click('a.edit-button', index) world.wait_for_ajax_complete()
def save_component_and_reopen(step): world.css_click("a.save-button") world.wait_for_ajax_complete() # We have a known issue that modifications are still shown within the edit window after cancel (though) # they are not persisted. Refresh the browser to make sure the changes WERE persisted after Save. reload_the_page(step) edit_component_and_select_settings()
def select_editor_tab(tab_name): editor_tabs = world.browser.find_by_css('.editor-tabs a') expected_tab_text = tab_name.strip().upper() matching_tabs = [tab for tab in editor_tabs if tab.text.upper() == expected_tab_text] assert len(matching_tabs) == 1 tab = matching_tabs[0] tab.click() world.wait_for_ajax_complete()
def type_in_codemirror(index, text, find_prefix="$"): script = """ var cm = {find_prefix}('div.CodeMirror:eq({index})').get(0).CodeMirror; cm.getInputField().focus(); cm.setValue(arguments[0]); cm.getInputField().blur();""".format(index=index, find_prefix=find_prefix) world.browser.driver.execute_script(script, str(text)) world.wait_for_ajax_complete()
def check_problem(step): # first scroll down so the loading mathjax button does not # cover up the Check button world.browser.execute_script("window.scrollTo(0,1024)") world.css_click("button.check") # Wait for the problem to finish re-rendering world.wait_for_ajax_complete()
def _transcripts_are_downloaded(): world.wait_for_ajax_complete() request = RequestHandler() DOWNLOAD_BUTTON = world.css_find(TRANSCRIPTS_BUTTONS["download_to_edit"][0]).first url = DOWNLOAD_BUTTON["href"] request.connect(url) return request.status_code.is_success()
def add_video_to_course(course, parent_location=None, player_mode=None, data=None, display_name='Video'): if not parent_location: parent_location = add_vertical_to_course(course) kwargs = get_metadata(parent_location, player_mode, data, display_name=display_name) world.scenario_dict['VIDEO'] = world.ItemFactory.create(**kwargs) world.wait_for_present('.is-initialized') world.wait_for_invisible('.video-wrapper .spinner') world.wait_for_ajax_complete()
def select_the_verified_track(step): create_cert_course() register() select_contribution(32) world.wait_for_ajax_complete() btn_css = 'input[value="Select Certificate"]' world.css_click(btn_css) assert world.is_css_present('section.progress')
def click_button_index(_step, button_type, index): world.wait(DELAY) world.wait_for_ajax_complete() button = button_type.strip() index = int(index.strip()) - 1 world.css_click(TRANSCRIPTS_BUTTONS[button][0], index)
def wait_for_problem(display_name): """ Wait for the problem with `display_name` to appear on the page. """ # Wait for the problem to reload world.wait_for_ajax_complete() wait_func = lambda _: world.css_has_text(".problem-header", display_name, strip=True) world.wait_for(wait_func)
def check_transcripts_field(_step, values, field_name): world.wait(DELAY) world.wait_for_ajax_complete() world.click_link_by_text('Advanced') field_id = '#' + world.browser.find_by_xpath('//label[text()="%s"]' % field_name.strip())[0]['for'] values_list = [i.strip() == world.css_value(field_id) for i in values.split('|')] assert any(values_list) world.click_link_by_text('Basic')
def reload_the_page(step): world.wait_for_ajax_complete() world.browser.reload() requirements = None for test, req in REQUIREJS_WAIT.items(): if test.search(world.browser.url): requirements = req break world.wait_for_requirejs(requirements)
def i_see_button(_step, not_see, button_type): world.wait(DELAY) world.wait_for_ajax_complete() button = button_type.strip() if not_see.strip(): assert world.is_css_not_present(TRANSCRIPTS_BUTTONS[button][0]) else: assert world.css_has_text(TRANSCRIPTS_BUTTONS[button][0], TRANSCRIPTS_BUTTONS[button][1])
def clear_field(_step, index): index = int(index) - 1 world.css_fill(SELECTORS['url_inputs'], '', index) # For some reason ChromeDriver doesn't trigger an 'input' event after filling # the field with an empty value. That's why we trigger it manually via jQuery. world.trigger_event(SELECTORS['url_inputs'], event='input', index=index) world.wait(DELAY) world.wait_for_ajax_complete()
def click_button(_step, button): world.css_click(VIDEO_BUTTONS[button]) if button == "play": # Needs to wait for video buffrization world.wait_for( func=lambda _: world.css_has_class('.video', 'is-playing') and world.is_css_present(VIDEO_BUTTONS['pause']), timeout=30 ) world.wait_for_ajax_complete()
def check_visibility(self, step, visible): r"the conditional contents are (?P<visible>\w+)$" world.wait_for_ajax_complete() assert_in(visible, ("visible", "hidden")) if visible == "visible": world.wait_for_visible(".hidden-contents") assert_true(world.css_visible(".hidden-contents")) else: assert_true(world.is_css_not_present(".hidden-contents"))
def add_video_to_course(course, parent_location=None, player_mode=None, data=None, display_name='Video'): assert_less(world.youtube.config['youtube_api_response'].status_code, 400, "Real Youtube server is unavailable") if not parent_location: parent_location = add_vertical_to_course(course) kwargs = get_metadata(parent_location, player_mode, data, display_name=display_name) world.scenario_dict['VIDEO'] = world.ItemFactory.create(**kwargs) world.wait_for_present('.is-initialized') world.wait_for_invisible('.video-wrapper .spinner') world.wait_for_ajax_complete()
def check_visibility(self, step, visible): r'the conditional contents are (?P<visible>\w+)$' world.wait_for_ajax_complete() assert_in(visible, ('visible', 'hidden')) if visible == 'visible': world.wait_for_visible('.hidden-contents') assert_true(world.css_visible('.hidden-contents')) else: assert_true(world.is_css_not_present('.hidden-contents'))
def set_value_transcripts_field(_step, value, field_name): XPATH = '//label[text()="{name}"]'.format(name=field_name) SELECTOR = "#" + world.browser.find_by_xpath(XPATH)[0]["for"] element = world.css_find(SELECTOR).first if element["type"] == "text": SCRIPT = '$("{selector}").val("{value}").change()'.format(selector=SELECTOR, value=value) world.browser.execute_script(SCRIPT) assert world.css_has_value(SELECTOR, value) else: assert False, "Incorrect element type." world.wait_for_ajax_complete()
def i_enter_a_source(_step, link, index): index = int(index) - 1 if index is not 0 and not world.css_visible(SELECTORS["collapse_bar"]): world.css_click(SELECTORS["collapse_link"]) assert world.css_visible(SELECTORS["collapse_bar"]) world.css_fill(SELECTORS["url_inputs"], link, index) world.wait(DELAY) world.wait_for_ajax_complete()
def do_not_see_or_not_button_video(_step, action, button_type): world.wait(DELAY) world.wait_for_ajax_complete() action = action.strip() button = button_type.strip() if action == 'do not': assert not world.is_css_present(VIDEO_BUTTONS[button]) elif action == 'can': assert world.css_visible(VIDEO_BUTTONS[button]) else: raise ValueError('Parameter `action` should be one of "do not" or "can".')
def press_the_notification_button(_step, name): # Because the notification uses a CSS transition, # Selenium will always report it as being visible. # This makes it very difficult to successfully click # the "Save" button at the UI level. # Instead, we use JavaScript to reliably click # the button. btn_css = 'div#page-notification button.action-%s' % name.lower() world.trigger_event(btn_css, event='focus') world.browser.execute_script("$('{}').click()".format(btn_css)) world.wait_for_ajax_complete()
def check_link_in_link_plugin(step, path): # Ensure caret position is within the link just created. script = """ var editor = tinyMCE.activeEditor; editor.selection.select(editor.dom.select('a')[0]);""" world.browser.driver.execute_script(script) world.wait_for_ajax_complete() use_plugin( '.mce-i-link', lambda: assert_equal(path, world.css_find('.mce-textbox')[0].value) )
def press_the_notification_button(_step, name): # Because the notification uses a CSS transition, # Selenium will always report it as being visible. # This makes it very difficult to successfully click # the "Save" button at the UI level. # Instead, we use JavaScript to reliably click # the button. btn_css = 'div#page-notification a.action-%s' % name.lower() world.trigger_event(btn_css, event='focus') world.browser.execute_script("$('{}').click()".format(btn_css)) world.wait_for_ajax_complete()
def i_see_button_with_custom_text(_step, not_see, button_type, custom_text, index): world.wait(DELAY) world.wait_for_ajax_complete() button = button_type.strip() custom_text = custom_text.strip() index = int(index.strip()) - 1 if not_see.strip(): assert world.is_css_not_present(TRANSCRIPTS_BUTTONS[button][0]) else: assert world.css_has_text(TRANSCRIPTS_BUTTONS[button][0], TRANSCRIPTS_BUTTONS[button][1].format(custom_text), index)
def select_language(_step, code): _open_menu("language") selector = VIDEO_MENUS["language"] + ' li[data-lang-code={code}]'.format( code=code) item = world.css_find(selector) item.click() assert world.css_has_class(selector, 'active') assert len(world.css_find(VIDEO_MENUS["language"] + ' li.active')) == 1 assert world.css_visible('.subtitles') world.wait_for_ajax_complete()
def do_not_see_or_not_button_video(_step, action, button_type): world.wait(DELAY) world.wait_for_ajax_complete() action = action.strip() button = button_type.strip() if action == 'do not': assert not world.is_css_present(VIDEO_BUTTONS[button]) elif action == 'can': assert world.css_visible(VIDEO_BUTTONS[button]) else: raise ValueError( 'Parameter `action` should be one of "do not" or "can".')
def i_edit_blank_problem_for_annotation_response(_step): edit_css = """$('.component-header:contains("Blank Advanced Problem")').parent().find('a.edit-button').click()""" text = """ <problem> <annotationresponse> <annotationinput><text>Text of annotation</text></annotationinput> </annotationresponse> </problem>""" world.browser.execute_script(edit_css) world.wait_for_ajax_complete() type_in_codemirror(0, text) world.save_component()
def set_value_transcripts_field(_step, value, field_name): tab = world.css_find('#settings-tab').first XPATH = './/label[text()="{name}"]'.format(name=field_name) SELECTOR = '#' + tab.find_by_xpath(XPATH)[0]['for'] element = world.css_find(SELECTOR).first if element['type'] == 'text': SCRIPT = '$("{selector}").val("{value}").change()'.format( selector=SELECTOR, value=value) world.browser.execute_script(SCRIPT) assert world.css_has_value(SELECTOR, value) else: assert False, 'Incorrect element type.' world.wait_for_ajax_complete()
def upload_file(filename, sub_path=''): # The file upload dialog is a faux modal, a div that takes over the display attach_file(filename, sub_path) modal_css = 'div.wrapper-modal-window-assetupload' button_css = '{} .action-upload'.format(modal_css) world.css_click(button_css) # Clicking the Upload button triggers an AJAX POST. world.wait_for_ajax_complete() # The modal stays up with a "File uploaded succeeded" confirmation message, then goes away. # It should take under 2 seconds, so wait up to 10. # Note that is_css_not_present will return as soon as the element is gone. assert world.is_css_not_present(modal_css, wait_time=10)
def clickActionLink(checklist, task, actionText): # text will be empty initially, wait for it to populate def verify_action_link_text(driver): actualText = world.css_text('#course-checklist' + str(checklist) + ' a', index=task) if actualText == actionText: return True else: # toggle checklist item to make sure that the link button is showing toggleTask(checklist, task) return False world.wait_for(verify_action_link_text) world.css_click('#course-checklist' + str(checklist) + ' a', index=task) world.wait_for_ajax_complete()
def clear_fields(_step): # Clear the input fields and trigger an 'input' event script = """ $('{selector}') .prop('disabled', false) .removeClass('is-disabled') .val('') .trigger('input'); """.format(selector=SELECTORS['url_inputs']) world.browser.execute_script(script) world.wait(DELAY) world.wait_for_ajax_complete()
def clear_fields(_step): js_str = ''' $('{selector}') .eq({index}) .prop('disabled', false) .removeClass('is-disabled'); ''' for index in range(1, 4): js = js_str.format(selector=SELECTORS['url_inputs'], index=index - 1) world.browser.execute_script(js) _clear_field(index) world.wait(DELAY) world.wait_for_ajax_complete()
def type_in_codemirror(index, text): world.wait(1) # For now, slow this down so that it works. TODO: fix it. world.css_click("div.CodeMirror-lines", index=index) world.browser.execute_script( "$('div.CodeMirror.CodeMirror-focused > div').css('overflow', '')") g = world.css_find("div.CodeMirror.CodeMirror-focused > div > textarea") if world.is_mac(): g._element.send_keys(Keys.COMMAND + 'a') else: g._element.send_keys(Keys.CONTROL + 'a') g._element.send_keys(Keys.DELETE) g._element.send_keys(text) if world.is_firefox(): world.trigger_event('div.CodeMirror', index=index, event='blur') world.wait_for_ajax_complete()
def check_visibility(self, step, visible): r'the conditional contents are (?P<visible>\w+)$' world.wait_for_ajax_complete() assert_in(visible, ('visible', 'hidden')) if visible == 'visible': world.wait_for_visible('.hidden-contents') assert_true(world.css_visible('.hidden-contents')) else: assert_true(world.is_css_not_present('.hidden-contents')) assert_true( world.css_contains_text( '.conditional-message', 'must be attempted before this will become visible.'))
def select_transcript_format(_step, format): button_selector = '.video-tracks .a11y-menu-button' menu_selector = VIDEO_MENUS['download_transcript'] button = world.css_find(button_selector).first button.mouse_over() assert world.css_has_text(button_selector, '...', strip=True) menu_items = world.css_find(menu_selector + ' a') for item in menu_items: if item['data-value'] == format: item.click() world.wait_for_ajax_complete() break assert world.css_find(menu_selector + ' .active a')[0]['data-value'] == format assert world.css_has_text(button_selector, '.' + format, strip=True)
def select_language(_step, code): # Make sure that all ajax requests that affects the language menu are finished. # For example, request to get new translation etc. world.wait_for_ajax_complete() selector = VIDEO_MENUS["language"] + ' li[data-lang-code="{code}"]'.format( code=code) world.css_find(VIDEO_BUTTONS["CC"])[0].mouse_over() world.css_click(selector) assert world.css_has_class(selector, 'active') assert len(world.css_find(VIDEO_MENUS["language"] + ' li.active')) == 1 # Make sure that all ajax requests that affects the display of captions are finished. # For example, request to get new translation etc. world.wait_for_ajax_complete() world.wait_for_visible('.subtitles')
def _do_studio_prompt_action(intent, action): """ Wait for a studio prompt to appear and press the specified action button See cms/static/js/views/feedback_prompt.js for implementation """ assert intent in [ 'warning', 'error', 'confirmation', 'announcement', 'step-required', 'help', 'mini' ] assert action in ['primary', 'secondary'] world.wait_for_present( 'div.wrapper-prompt.is-shown#prompt-{}'.format(intent)) action_css = 'li.nav-item > a.action-{}'.format(action) world.trigger_event(action_css, event='focus') world.browser.execute_script("$('{}').click()".format(action_css)) world.wait_for_ajax_complete() world.wait_for_present( 'div.wrapper-prompt.is-hiding#prompt-{}'.format(intent))
def answer_poll(self, step, answer): r' I answer the conditioned poll "([^"]*)"$' visit_scenario_item('CONDITION_SOURCE') world.wait_for_js_variable_truthy( '$(".xblock-student_view[data-type=Poll]").data("initialized")') world.wait_for_ajax_complete() answer_text = [ poll_answer['text'] for poll_answer in world.scenario_dict['CONDITION_SOURCE'].answers if poll_answer['id'] == answer ][0] text_selector = '.poll_answer .text' poll_texts = world.retry_on_exception( lambda: [elem.text for elem in world.css_find(text_selector)]) for idx, poll_text in enumerate(poll_texts): if poll_text == answer_text: world.css_click(text_selector, index=idx) return
def select_transcript_format(_step, format): button_selector = '.video-tracks .a11y-menu-button' menu_selector = VIDEO_MENUS['download_transcript'] button = world.css_find(button_selector).first height = button._element.location_once_scrolled_into_view['y'] world.browser.driver.execute_script("window.scrollTo(0, {});".format(height)) button.mouse_over() assert world.css_has_text(button_selector, '...', strip=True) menu_items = world.css_find(menu_selector + ' a') for item in menu_items: if item['data-value'] == format: item.click() world.wait_for_ajax_complete() break world.browser.driver.execute_script("window.scrollTo(0, 0);") assert world.css_find(menu_selector + ' .active a')[0]['data-value'] == format assert world.css_has_text(button_selector, '.' + format, strip=True)
def i_created_a_video_with_subs_with_name(_step, sub_id): _step.given('I have created a Video component') # Store the current URL so we can return here video_url = world.browser.url # Upload subtitles for the video using the upload interface _step.given('I have uploaded subtitles "{}"'.format(sub_id)) # Return to the video world.visit(video_url) world.wait_for_xmodule() # update .sub filed with proper subs name (which mimics real Studio/XML behavior) # this is needed only for that videos which are created in acceptance tests. _step.given('I edit the component') world.wait_for_ajax_complete() _step.given('I save changes') world.disable_jquery_animations() world.wait_for_present('.is-initialized') world.wait_for_invisible(SELECTORS['spinner'])
def save_component(): world.css_click("a.action-save,a.save-button") world.wait_for_ajax_complete()
def switch_view(_step, view): staff_status = world.css_find('#staffstatus').first if staff_status.text != view: world.css_click('#staffstatus') world.wait_for_ajax_complete()
def click_button_video(_step, button_type): world.wait(DELAY) world.wait_for_ajax_complete() button = button_type.strip() world.css_click(VIDEO_BUTTONS[button])
def click_button_index(_step, button_type, index): button = button_type.strip() index = int(index.strip()) - 1 world.css_click(TRANSCRIPTS_BUTTONS[button][0], index) world.wait_for_ajax_complete()
def upload_file(_step, file_name): path = os.path.join(TEST_ROOT, 'uploads/', file_name.strip()) world.browser.execute_script("$('form.file-chooser').show()") world.browser.attach_file('transcript-file', os.path.abspath(path)) world.wait_for_ajax_complete()
def submit_payment(step): # First make sure that the page is done if it still executing # an ajax query. world.wait_for_ajax_complete() button_css = 'input[value=Submit]' world.css_click(button_css)
def click_button_transcripts_variant(_step, button_type): button = button_type.strip() world.css_click(TRANSCRIPTS_BUTTONS[button][0]) world.wait_for_ajax_complete()
def click_verified_track_button(): world.wait_for_ajax_complete() btn_css = 'input[value="Select Certificate"]' world.css_click(btn_css)
def reload_the_page(step): world.wait_for_ajax_complete() world.browser.reload() world.wait_for_js_to_load()
def reset_problem(_step): world.css_click('input.reset') # Wait for the problem to finish re-rendering world.wait_for_ajax_complete()
def change_value(step, key, new_value): index = get_index_of(key) type_in_codemirror(index, new_value) press_the_notification_button(step, "Save") world.wait_for_ajax_complete()
def set_date_and_time(date_css, desired_date, time_css, desired_time, key=None): set_element_value(date_css, desired_date, key) world.wait_for_ajax_complete() set_element_value(time_css, desired_time, key) world.wait_for_ajax_complete()