def create_latex_problem(step): world.click_new_component_button(step, '.large-problem-icon') # Go to advanced tab (waiting for the tab to be visible) world.css_find('#ui-id-2') world.css_click('#ui-id-2') world.click_component_from_menu( "i4x://edx/templates/problem/Problem_Written_in_LaTeX", '.xmodule_CapaModule')
def assert_answer_mark(_step, problem_type, isnt_marked, correctness): """ Assert that the expected answer mark is visible for a given problem type. *problem_type* is a string identifying the type of problem (e.g. 'drop down') *correctness* is in ['correct', 'incorrect', 'unanswered'] """ # Determine which selector(s) to look for based on correctness assert(correctness in ['correct', 'incorrect', 'unanswered']) assert(problem_type in PROBLEM_DICT) # At least one of the correct selectors should be present for sel in PROBLEM_DICT[problem_type][correctness]: if bool(isnt_marked): world.wait_for(lambda _: world.is_css_not_present(sel)) # pylint: disable=cell-var-from-loop has_expected = world.is_css_not_present(sel) else: world.css_find(sel) # css_find includes a wait_for pattern has_expected = world.is_css_present(sel) # As soon as we find the selector, break out of the loop if has_expected: break # Expect that we found the expected selector assert(has_expected)
def css_check(css_selector, index=0, max_attempts=5, success_condition=lambda: True): """ Checks a check box based on a CSS selector, retrying if it initially fails. This function handles errors that may be thrown if the component cannot be clicked on. However, there are cases where an error may not be thrown, and yet the operation did not actually succeed. For those cases, a success_condition lambda can be supplied to verify that the check worked. This function will return True if the check worked (taking into account both errors and the optional success_condition). """ assert is_css_present(css_selector) attempt = 0 result = False while attempt < max_attempts: try: world.css_find(css_selector)[index].check() if success_condition(): result = True break except WebDriverException: # Occasionally, MathJax or other JavaScript can cover up # an element temporarily. # If this happens, wait a second, then try again world.wait(1) attempt += 1 except: attempt += 1 return result
def test_i_receive_a_warning_about_course_start_date(step): assert_true(world.css_has_text('.message-error', 'The course must have an assigned start date.')) assert_true('error' in world.css_find( COURSE_START_DATE_CSS).first._element.get_attribute('class')) assert_true('error' in world.css_find( COURSE_START_TIME_CSS).first._element.get_attribute('class'))
def check_toolbar_buttons(step): dropdowns = world.css_find('.mce-listbox') assert_equal(2, len(dropdowns)) # Format dropdown assert_equal('Paragraph', dropdowns[0].text) # Font dropdown assert_equal('Font Family', dropdowns[1].text) buttons = world.css_find('.mce-ico') # Note that the code editor icon is not present because we are now showing text instead of an icon. # However, other test points user the code editor, so we have already verified its presence. expected_buttons = [ 'bold', 'italic', 'underline', 'forecolor', # This is our custom "code style" button, which uses an image instead of a class. 'none', 'bullist', 'numlist', 'outdent', 'indent', 'blockquote', 'link', 'unlink', 'image' ] assert_equal(len(expected_buttons), len(buttons)) for index, button in enumerate(expected_buttons): class_names = buttons[index]._element.get_attribute('class') assert_equal("mce-ico mce-i-" + button, class_names)
def css_check(css_selector, index=0, max_attempts=5, success_condition=lambda: True): """ Checks a check box based on a CSS selector, retrying if it initially fails. This function handles errors that may be thrown if the component cannot be clicked on. However, there are cases where an error may not be thrown, and yet the operation did not actually succeed. For those cases, a success_condition lambda can be supplied to verify that the check worked. This function will return True if the check worked (taking into account both errors and the optional success_condition). """ assert is_css_present(css_selector), "{} is not present".format(css_selector) for _ in range(max_attempts): try: world.css_find(css_selector)[index].check() if success_condition(): return except WebDriverException: # Occasionally, MathJax or other JavaScript can cover up # an element temporarily. # If this happens, wait a second, then try again world.wait(1) except: pass else: # try once more, letting exceptions raise world.css_find(css_selector)[index].check() if not success_condition(): raise Exception("unsuccessful check")
def videos_are_rendered(_step, mode): modes = {"html5": "video", "youtube": "iframe", "flash": "iframe"} html_tag = modes[mode.lower()] actual = len(world.css_find(".video {0}".format(html_tag))) expected = len(world.css_find(".xmodule_VideoModule")) assert actual == expected
def check_textbook_chapters(_step, textbook_name, num_chapters_str): num_chapters = int(num_chapters_str) title = world.css_find(".textbook .view-textbook h3.textbook-title") toggle = world.css_find(".textbook .view-textbook .chapter-toggle") assert title.text == textbook_name, "{} != {}".format(title.text, textbook_name) assert toggle.text == "{num} PDF Chapters".format(num=num_chapters), \ "Expected {num} chapters, found {real}".format(num=num_chapters, real=toggle.text)
def select_the_audit_track(step): create_cert_course() register() btn_css = 'input[value="Select Audit"]' world.wait(1) # TODO remove this after troubleshooting JZ world.css_find(btn_css) world.css_click(btn_css)
def get_index_of(expected_key): for counter in range(len(world.css_find(KEY_CSS))): # Sometimes get stale reference if I hold on to the array of elements key = world.css_find(KEY_CSS)[counter].value if key == expected_key: return counter return -1
def set_captions_visibility_state(_step, captions_state): SELECTOR = '.closed .subtitles' if world.is_css_not_present(SELECTOR): if captions_state == 'closed': world.css_find('.hide-subtitles').click() else: if captions_state != 'closed': world.css_find('.hide-subtitles').click()
def lock_unlock_file(_step, _lock_state): index = get_index('asset.html') assert index != -1, 'Expected to find an asset but could not.' # Warning: this is a misnomer, it really only toggles the # lock state. TODO: fix it. lock_css = "input.lock-checkbox" world.css_find(lock_css)[index].click()
def edit_the_value_of_a_policy_key(step): """ It is hard to figure out how to get into the CodeMirror area, so cheat and do it from the policy key field :) """ world.css_find(".CodeMirror")[get_index_of(DISPLAY_NAME_KEY)].click() g = world.css_find("div.CodeMirror.CodeMirror-focused > div > textarea") g._element.send_keys(Keys.ARROW_LEFT, ' ', 'X')
def i_click_the_foo_filter_link(step, text): link_css = 'form#coursefilter-form a' # For synchronization purposes, make sure the links # are there first world.css_find(link_css) if text in ['current', 'past', 'new']: text = text.upper() world.browser.find_link_by_text(text).click()
def view_lti_permission_alert(_step): assert not world.is_css_present('iframe', wait_time=2) assert world.is_css_present('.link_lti_new_window', wait_time=0) assert not world.is_css_present('.error_message', wait_time=0) world.css_find('.link_lti_new_window').first.click() alert = world.browser.get_alert() assert alert is not None assert len(world.browser.windows) == 1
def set_date_and_time(date_css, desired_date, time_css, desired_time): world.css_fill(date_css, desired_date) # hit TAB to get to the time field e = world.css_find(date_css).first e._element.send_keys(Keys.TAB) world.css_fill(time_css, desired_time) e = world.css_find(time_css).first e._element.send_keys(Keys.TAB) time.sleep(float(1))
def set_captions_visibility_state(_step, captions_state): SELECTOR = ".closed .subtitles" world.wait_for_visible(".hide-subtitles") if captions_state == "closed": if not world.is_css_present(SELECTOR): world.css_find(".hide-subtitles").click() else: if world.is_css_present(SELECTOR): world.css_find(".hide-subtitles").click()
def try_move(): handle = world.css_find(handle_selector).first slider = world.css_find('.gst-input .ui-slider').first (handle.action_chains .click_and_hold(handle._element) .move_by_offset( int(handle._element.location['x'] + 400), 0 ).release().perform())
def _verify_tab_names(first, second): world.wait_for( func=lambda _: len(world.css_find('.xmodule_StaticTabModule')) == 2, timeout=200, timeout_msg="Timed out waiting for two tabs to be present" ) tabs = world.css_find('.xmodule_StaticTabModule') assert tabs[0].text == first assert tabs[1].text == second
def set_captions_visibility_state(_step, captions_state): SELECTOR = '.closed .subtitles' world.wait_for_visible('.hide-subtitles') if captions_state == 'closed': if not world.is_css_present(SELECTOR): world.css_find('.hide-subtitles').click() else: if world.is_css_present(SELECTOR): world.css_find('.hide-subtitles').click()
def _verify_page_names(first, second): world.wait_for( func=lambda _: len(world.css_find('.xmodule_StaticTabModule')) == 2, timeout=200, timeout_msg="Timed out waiting for two pages to be present" ) pages = world.css_find('.xmodule_StaticTabModule') assert_equal(pages[0].text, first) assert_equal(pages[1].text, second)
def change_display_name_value(step, new_value): world.css_find(".CodeMirror")[get_index_of(DISPLAY_NAME_KEY)].click() g = world.css_find("div.CodeMirror.CodeMirror-focused > div > textarea") display_name = get_display_name_value() for count in range(len(display_name)): g._element.send_keys(Keys.END, Keys.BACK_SPACE) # Must delete "" before typing the JSON value g._element.send_keys(Keys.END, Keys.BACK_SPACE, Keys.BACK_SPACE, new_value) press_the_notification_button(step, "Save")
def change_value(step, key, new_value): index = get_index_of(key) world.css_find(".CodeMirror")[index].click() g = world.css_find("div.CodeMirror.CodeMirror-focused > div > textarea") current_value = world.css_find(VALUE_CSS)[index].value g._element.send_keys(Keys.CONTROL + Keys.END) for count in range(len(current_value)): g._element.send_keys(Keys.END, Keys.BACK_SPACE) # Must delete "" before typing the JSON value g._element.send_keys(Keys.END, Keys.BACK_SPACE, Keys.BACK_SPACE, new_value) press_the_notification_button(step, "Save")
def see_assignment_name(step, do_not, name): assignment_menu_css = 'ul.menu > li > a' # First assert that it is there, make take a bit to redraw assert world.css_find(assignment_menu_css) assignment_menu = world.css_find(assignment_menu_css) allnames = [item.html for item in assignment_menu] if do_not: assert_not_in(name, allnames) else: assert_in(name, allnames)
def videos_are_rendered(_step, mode): modes = { 'html5': 'video', 'youtube': 'iframe', 'flash': 'iframe', } html_tag = modes[mode.lower()] actual = len(world.css_find('.video {0}'.format(html_tag))) expected = len(world.css_find('.xmodule_VideoModule')) assert actual == expected
def change_name(_step, new_name): settings_css = '#settings-mode' world.css_find(settings_css).click() input_css = 'input.setting-input' name_input = world.css_find(input_css) old_name = name_input.value for count in range(len(old_name)): name_input._element.send_keys(Keys.END, Keys.BACK_SPACE) name_input._element.send_keys(new_name) save_button = 'a.save-button' world.css_find(save_button).click()
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(_step, file_name): upload_css = 'a.upload-button' world.css_find(upload_css).click() file_css = 'input.file-input' upload = world.css_find(file_css) #uploading the file itself path = os.path.join(TEST_ROOT, 'uploads/', file_name) upload._element.send_keys(os.path.abspath(path)) close_css = 'a.close-button' world.css_find(close_css).click()
def verifyChecklist2Status(completed, total, percentage): def verify_count(driver): try: statusCount = world.css_find('#course-checklist1 .status-count').first return statusCount.text == str(completed) except StaleElementReferenceException: return False world.wait_for(verify_count) assert_equal(str(total), world.css_find('#course-checklist1 .status-amount').first.text) # Would like to check the CSS width, but not sure how to do that. assert_equal(str(percentage), world.css_find('#course-checklist1 .viz-checklist-status-value .int').first.text)
def click_reply(self, step, problem): r"""I click "Reply to annotation" on passage (?P<problem>\d+)$""" problem = int(problem) annotation_span_selector = '.annotatable-span[data-problem-id="{}"]'.format(problem) world.css_find(annotation_span_selector).first.mouse_over() annotation_reply_selector = '.annotatable-reply[data-problem-id="{}"]'.format(problem) assert_equals(len(world.css_find(annotation_reply_selector)), 1) world.css_click(annotation_reply_selector) self.active_problem = problem
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 does_not_autoplay(_step, video_type): actual = world.css_find('.%s' % video_type)[0]['data-autoplay'] expected = [u'False', u'false', False] assert actual in expected
def get_setting(): settings = world.css_find('.wrapper-comp-setting') for setting in settings: if setting.find_by_css('.setting-label')[0].value == label: return setting return None
def i_see_the_assignment_type(_step, name): assignment_css = '#course-grading-assignment-name' assignments = world.css_find(assignment_css) types = [ele['value'] for ele in assignments] assert name in types
def confirm_change(step): range_css = '.range' all_ranges = world.css_find(range_css) for i in range(len(all_ranges)): assert_not_equal(world.css_html(range_css, index=i), '0-50')
def see_the_payment_page(step): assert world.css_find('button#pay_button')
def navigate_to_my_dashboard(step): world.css_click('span.avatar') assert world.css_find('section.my-courses')
def see_that_my_payment_was_successful(step): title = world.css_find('div.wrapper-content-main h3.title') assert_equal(title.text, u'Congratulations! You are now verified on edX.')
def inputs_are_enabled(_step): for index in range(3): el = world.css_find(SELECTORS['url_inputs'])[index] assert not el['disabled']
def click_and_check_lti_popup(): parent_window = world.browser.current_window # Save the parent window world.css_find('.link_lti_new_window').first.click() check_lti_popup(parent_window)
def see_graph(_step, progress): assert_equal( progress, world.css_find('#grade-detail-graph .overallGrade').first.text.split( '\n')[1])
def view_grade_slider(step, how_many): grade_slider_css = '.grade-specific-bar' all_grades = world.css_find(grade_slider_css) assert_equal(len(all_grades), int(how_many))
def move_grade_slider(step): moveable_css = '.ui-resizable-e' f = world.css_find(moveable_css).first f.action_chains.drag_and_drop_by_offset(f._element, 100, 0).perform()
def select_contribution(amount=32): radio_css = 'input[value="{}"]'.format(amount) world.css_click(radio_css) assert world.css_find(radio_css).selected
def get_url(): return world.css_find(url_css)[index]._element.get_attribute('href')
def all_sections_are_expanded(step): subsection_locator = 'div.subsection-list' subsections = world.css_find(subsection_locator) for s in subsections: assert_true(s.visible)
def change_grade_range(_step, range_name): range_css = 'span.letter-grade' grade = world.css_find(range_css).first grade.value = range_name
def found_css_func(css): return lambda: world.is_css_present(css, wait_time=2) COMPONENT_DICTIONARY = { 'Discussion': { 'steps': step_selector_list('discussion', None), 'found_func': found_css_func('section.xmodule_DiscussionModule') }, 'Blank HTML': { 'steps': step_selector_list('html', 'Blank_HTML_Page'), #this one is a blank html so a more refined search is being done 'found_func': lambda: '\n \n' in [x.html for x in world.css_find('section.xmodule_HtmlModule')] }, 'LaTex': { 'steps': step_selector_list('html', 'E-text_Written_in_LaTeX'), 'found_func': found_text_func('EXAMPLE: E-TEXT PAGE') }, 'Blank Problem': { 'steps': step_selector_list('problem', 'Blank_Common_Problem'), 'found_func': found_text_func('BLANK COMMON PROBLEM') }, 'Dropdown': { 'steps': step_selector_list('problem', 'Dropdown'), 'found_func': found_text_func('DROPDOWN') }, 'Multi Choice': { 'steps': step_selector_list('problem', 'Multiple_Choice'),
def all_sources_are_correct(_step): elements = world.css_find('.video-player video source') sources = [source['src'].split('?')[0] for source in elements] assert set(sources) == set(HTML5_SOURCES)
def get_index(): settings = world.css_find('.wrapper-comp-setting') for index, setting in enumerate(settings): if setting.find_by_css('.setting-label')[0].value == label: return index return None
def check_link_in_image_plugin(step, path): use_plugin( '.mce-i-image', lambda: assert_equal(path, world.css_find('.mce-textbox')[0].value))
def check_page_text(step): assert_in(step.multiline, world.css_find('.xmodule_HtmlModule').html)
def add_assignment_type(step, new_name): add_button_css = '.add-grading-data' world.css_click(add_button_css) name_id = '#course-grading-assignment-name' new_assignment = world.css_find(name_id)[-1] new_assignment._element.send_keys(new_name)
def i_see_highest_grade_range(_step, range_name): range_css = 'span.letter-grade' grade = world.css_find(range_css).first assert_equal(grade.value, range_name)
def all_sections_are_collapsed(step): subsection_locator = 'div.subsection-list' subsections = world.css_find(subsection_locator) for s in subsections: assert_false(s.visible)
def at_the_payment_page(step): assert world.css_find('input[name=transactionSignature]')
def i_see_the_span_with_text(step, text): span_locator = '.toggle-button-sections span' assert_true(world.is_css_present(span_locator)) assert_equal(world.css_find(span_locator).value, text) assert_true(world.css_visible(span_locator))
def get_display_name_value(): index = get_index_of(DISPLAY_NAME_KEY) return world.css_find(VALUE_CSS)[index].value
def inputs_are_disabled(_step, indexes): index_list = [int(i.strip()) - 1 for i in indexes.split(',')] for index in index_list: el = world.css_find(SELECTORS['url_inputs'])[index] assert el['disabled']
def change_grading_status(step): world.css_find('a.menu-toggle').click() world.css_find('.menu li').first.click()