def see_component_in_position(step, display_name, index): component_css = 'div.xmodule_CapaModule' def find_problem(_driver): return world.css_text(component_css, int(index)).startswith(display_name.upper()) world.wait_for(find_problem, timeout_msg='Did not find the duplicated problem')
def i_click_on_the_tab_and_check(step): for tab_title in step.hashes: tab_text = tab_title['TabName'] title = tab_title['PageTitle'] world.click_link(tab_text) world.wait_for(lambda _driver:title in world.browser.title) assert(title in world.browser.title)
def see_score(_step, score): # The problem progress is changed by # cms/static/xmodule_js/src/capa/display.js # so give it some time to render on the page. score_css = 'div.problem-progress' expected_text = '({})'.format(score) world.wait_for(lambda _: world.css_has_text(score_css, expected_text))
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 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 create_component_instance(step, category, component_type=None, is_advanced=False): """ Create a new component in a Unit. Parameters ---------- category: component type (discussion, html, problem, video) component_type: for components with multiple templates, the link text in the menu is_advanced: for html and problem, is the desired component under the advanced menu """ assert_in(category, ['problem', 'html', 'video', 'discussion']) component_button_css = 'span.large-{}-icon'.format(category.lower()) if category == 'problem': module_css = 'section.xmodule_CapaModule' else: module_css = 'section.xmodule_{}Module'.format(category.title()) # Count how many of that module is on the page. Later we will # assert that one more was added. # We need to use world.browser.find_by_css instead of world.css_find # because it's ok if there are currently zero of them. module_count_before = len(world.browser.find_by_css(module_css)) world.css_click(component_button_css) if category in ('problem', 'html'): world.wait_for_invisible(component_button_css) click_component_from_menu(category, component_type, is_advanced) world.wait_for(lambda _: _is_expected_element_count(module_css, module_count_before + 1))
def see_a_multi_step_component(step, category): # Wait for all components to finish rendering selector = 'li.studio-xblock-wrapper div.xblock-student_view' world.wait_for(lambda _: len(world.css_find(selector)) == len(step.hashes)) for idx, step_hash in enumerate(step.hashes): if category == 'HTML': html_matcher = { 'Text': '\n \n', 'Announcement': '<p> Words of encouragement! This is a short note that most students will read. </p>', 'Zooming Image': '<h2>ZOOMING DIAGRAMS</h2>', 'E-text Written in LaTeX': '<h2>Example: E-text page</h2>', 'Raw HTML': '<p>This template is similar to the Text template. The only difference is', } actual_html = world.css_html(selector, index=idx) assert_in(html_matcher[step_hash['Component']], actual_html) else: actual_text = world.css_text(selector, index=idx) assert_in(step_hash['Component'].upper(), actual_text)
def css_has_text(css_selector, text, index=0, strip=False, allow_blank=True): """ Return a boolean indicating whether the element with `css_selector` has `text`. If `strip` is True, strip whitespace at beginning/end of both strings before comparing. If `allow_blank` is False, wait for the element to have non-empty text before making the assertion. This is useful for elements that are populated by JavaScript after the page loads. If there are multiple elements matching the css selector, use `index` to indicate which one. """ if not allow_blank: world.wait_for(lambda _: world.css_text(css_selector, index=index)) actual_text = world.css_text(css_selector, index=index) if strip: actual_text = actual_text.strip() text = text.strip() return actual_text == text
def start_playing_video_from_n_seconds(_step, position): world.wait_for(func=lambda _: elapsed_time() > 0, timeout=30) actual_position = elapsed_time() assert_equal( actual_position, int(position), "Current position is {}, but should be {}".format(actual_position, position) )
def open_new_unit(step): step.given('I have opened a new course section in Studio') step.given('I have added a new subsection') step.given('I expand the first section') old_url = world.browser.url world.css_click('a.new-unit-item') world.wait_for(lambda x: world.browser.url != old_url)
def i_see_duration(_step, position): world.wait_for( func=lambda _: duration() > 0, timeout=30 ) assert duration() == parse_time_str(position)
def create_component_instance(step, category, component_type=None, is_advanced=False): """ Create a new component in a Unit. Parameters ---------- category: component type (discussion, html, problem, video) component_type: for components with multiple templates, the link text in the menu is_advanced: for problems, is the desired component under the advanced menu? """ assert_in(category, ["problem", "html", "video", "discussion"]) component_button_css = "span.large-{}-icon".format(category.lower()) if category == "problem": module_css = "section.xmodule_CapaModule" else: module_css = "section.xmodule_{}Module".format(category.title()) # Count how many of that module is on the page. Later we will # assert that one more was added. # We need to use world.browser.find_by_css instead of world.css_find # because it's ok if there are currently zero of them. module_count_before = len(world.browser.find_by_css(module_css)) # Disable the jquery animation for the transition to the menus. world.disable_jquery_animations() world.css_click(component_button_css) if category in ("problem", "html"): world.wait_for_invisible(component_button_css) click_component_from_menu(category, component_type, is_advanced) expected_count = module_count_before + 1 world.wait_for(lambda _: len(world.css_find(module_css)) == expected_count, timeout=20)
def find_student_profile_table(step): # pylint: disable=unused-argument # Find the grading configuration display world.wait_for_visible('#data-student-profiles-table') # Wait for the data table to be populated world.wait_for(lambda _: world.css_text('#data-student-profiles-table') not in [u'', u'Loading']) if world.role == 'instructor': expected_data = [ world.instructor.username, world.instructor.email, world.instructor.profile.name, world.instructor.profile.gender, world.instructor.profile.goals ] elif world.role == 'staff': expected_data = [ world.staff.username, world.staff.email, world.staff.profile.name, world.staff.profile.gender, world.staff.profile.goals ] for datum in expected_data: assert_in(datum, world.css_text('#data-student-profiles-table'))
def wait_for_problem(display_name): """ Wait for the problem with `display_name` to appear on the page. """ wait_func = lambda _: world.css_has_text( 'h2.problem-header', display_name, strip=True ) world.wait_for(wait_func)
def see_page(step, page): # Need to retry here because the element # will sometimes exist before the HTML content is loaded exists_func = lambda(driver): page_exists(page) world.wait_for(exists_func) assert_true(exists_func(None))
def set_show_captions(step, setting): # Prevent cookies from overriding course settings world.browser.cookies.delete('hide_captions') world.css_click('a.edit-button') world.wait_for(lambda _driver: world.css_visible('a.save-button')) world.browser.select('Show Captions', setting) world.css_click('a.save-button')
def the_grace_period_is(_step, grace_period): grace_period_css = '#course-grading-graceperiod' # The default value is 00:00 # so we need to wait for it to change world.wait_for( lambda _: world.css_has_value(grace_period_css, grace_period) )
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 create_latex_problem(step): world.click_new_component_button(step, '.large-problem-icon') def animation_done(_driver): return world.browser.evaluate_script("$('div.new-component').css('display')") == 'none' world.wait_for(animation_done) # Go to advanced tab. world.css_click('#ui-id-2') world.click_component_from_menu("problem", "latex_problem.yaml", '.xmodule_CapaModule')
def set_show_captions(step, setting): # Prevent cookies from overriding course settings world.browser.cookies.delete("hide_captions") world.css_click("a.edit-button") world.wait_for(lambda _driver: world.css_visible("a.save-button")) world.click_link_by_text("Advanced") world.browser.select("Show Transcript", setting) world.css_click("a.save-button")
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_show_captions(step, setting): # Prevent cookies from overriding course settings world.browser.cookies.delete('hide_captions') world.css_click('a.edit-button') world.wait_for(lambda _driver: world.css_visible('a.save-button')) world.click_link_by_text('Advanced') world.browser.select('Transcript Display', setting) world.css_click('a.save-button')
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 seek_video_to_n_seconds(_step, time_str): time = parse_time_str(time_str) jsCode = "$('.video').data('video-player-state').videoPlayer.onSlideSeek({{time: {0}}})".format(time) world.browser.execute_script(jsCode) world.wait_for( func=lambda _: world.retry_on_exception(lambda: elapsed_time() == time and not world.css_has_class('.video', 'is-buffering')), timeout=30 ) _step.given('I see video slider at "{0}" position'.format(time_str))
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 i_see_new_course_image(_step): img_css = '#course-image' images = world.css_find(img_css) assert len(images) == 1 img = images[0] expected_src = 'image.jpg' # Don't worry about the domain in the URL success_func = lambda _: img['src'].endswith(expected_src) world.wait_for(success_func)
def log_into_studio( uname='robot', email='*****@*****.**', password='******', name='Robot Studio'): world.log_in(username=uname, password=password, email=email, name=name) # Navigate to the studio dashboard world.visit('/') world.wait_for(lambda _driver: uname in world.css_find('h2.title')[0].text)
def i_see_new_course_image(_step): img_css = "#course-image" images = world.css_find(img_css) assert len(images) == 1 img = images[0] expected_src = "/c4x/MITx/999/asset/image.jpg" # Don't worry about the domain in the URL success_func = lambda _: img["src"].endswith(expected_src) world.wait_for(success_func)
def clickActionLink(checklist, task, actionText): # toggle checklist item to make sure that the link button is showing toggleTask(checklist, task) action_link = world.css_find('#course-checklist' + str(checklist) + ' a')[task] # text will be empty initially, wait for it to populate def verify_action_link_text(driver): return world.css_text('#course-checklist' + str(checklist) + ' a', index=task) == actionText world.wait_for(verify_action_link_text) world.css_click('#course-checklist' + str(checklist) + ' a', index=task)
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 edit_component(): world.wait_for(lambda _driver: world.css_visible('a.edit-button')) world.css_click('a.edit-button')
def edit_component_and_select_settings(): world.wait_for(lambda _driver: world.css_visible('a.edit-button')) world.css_click('a.edit-button') world.css_click('#settings-mode a')