def fill_in_the_login_form(field, value): def fill_login_form(): login_form = world.browser.find_by_css('form#login-form') form_field = login_form.find_by_name(field) form_field.fill(value) world.retry_on_exception(fill_login_form)
def fill_field(name, info): def fill_info(): form_css = 'form.feedback_form' form = world.css_find(form_css) form.find_by_name(name).fill(info) world.retry_on_exception(fill_info)
def i_fill_in_the_signin_form(step): def fill_login_form(): login_form = world.browser.find_by_css('form#login_form') login_form.find_by_name('email').fill('*****@*****.**') login_form.find_by_name('password').fill('test') login_form.find_by_name('submit').click() world.retry_on_exception(fill_login_form)
def when_i_fill_in_field_on_the_registration_form_with_value( step, field, value): def fill_in_registration(): register_form = world.browser.find_by_css('form#register-form') form_field = register_form.find_by_name(field) form_field.fill(value) world.retry_on_exception(fill_in_registration)
def i_submit_my_credentials_on_the_login_form(step): fill_in_the_login_form('email', '*****@*****.**') fill_in_the_login_form('password', 'test') def submit_login_form(): login_form = world.browser.find_by_css('form#login-form') login_form.find_by_name('submit').click() world.retry_on_exception(submit_login_form)
def i_fill_in_the_registration_form(step): def fill_in_reg_form(): register_form = world.css_find('form#register_form') register_form.find_by_name('email').fill('*****@*****.**') register_form.find_by_name('password').fill('test') register_form.find_by_name('username').fill('robot-studio') register_form.find_by_name('name').fill('Robot Studio') register_form.find_by_name('terms_of_service').click() world.retry_on_exception(fill_in_reg_form)
def i_register_to_audit_the_course(_step): url = django_url('courses/%s/about' % world.scenario_dict['COURSE'].id.to_deprecated_string()) world.browser.visit(url) world.css_click('section.intro a.register') # When the page first loads some animation needs to # complete before this button is in a stable location world.retry_on_exception( lambda: world.browser.find_by_name("honor_mode").click(), max_attempts=10, ignored_exceptions=AttributeError ) time.sleep(1) assert world.is_css_present('section.container.dashboard')
def i_register_to_audit_the_course(_step): url = django_url('courses/%s/about' % world.scenario_dict['COURSE'].id.to_deprecated_string()) world.browser.visit(url) world.css_click('.intro a.register') # When the page first loads some animation needs to # complete before this button is in a stable location world.retry_on_exception( lambda: world.browser.find_by_name("honor_mode").click(), max_attempts=10, ignored_exceptions=AttributeError) time.sleep(1) assert world.is_css_present('.container.dashboard')
def move_slider(self, step): r'I move the slider to the right$' handle_selector = '.gst-input .ui-slider-handle' world.wait_for_visible(handle_selector) world.wait_for_visible('.gst-value #value-display') 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()) world.retry_on_exception(try_move)
def other_user_login(_step, name): world.browser.cookies.delete() world.visit('/') signin_css = 'a.action-signin' world.is_css_present(signin_css) world.css_click(signin_css) def fill_login_form(): login_form = world.browser.find_by_css('form#login_form') login_form.find_by_name('email').fill(name + EMAIL_EXTENSION) login_form.find_by_name('password').fill(PASSWORD) login_form.find_by_name('submit').click() world.retry_on_exception(fill_login_form) assert_true(world.is_css_present('.new-course-button')) world.scenario_dict['USER'] = get_user_by_email(name + EMAIL_EXTENSION)
def other_user_login(_step, name): world.visit('logout') world.visit('/') signin_css = 'a.action-signin' world.is_css_present(signin_css) world.css_click(signin_css) def fill_login_form(): login_form = world.browser.find_by_css('form#login_form') login_form.find_by_name('email').fill(name + EMAIL_EXTENSION) login_form.find_by_name('password').fill(PASSWORD) login_form.find_by_name('submit').click() world.retry_on_exception(fill_login_form) assert_true(world.is_css_present('.new-course-button')) world.scenario_dict['USER'] = get_user_by_email(name + EMAIL_EXTENSION)
def other_user_login(step, name): step.given('I log out') world.visit('/') signin_css = 'a.action-signin' world.is_css_present(signin_css) world.css_click(signin_css) def fill_login_form(): login_form = world.browser.find_by_css('form#login_form') login_form.find_by_name('email').fill(name + '@edx.org') login_form.find_by_name('password').fill("test") login_form.find_by_name('submit').click() world.retry_on_exception(fill_login_form) assert_true(world.is_css_present('.new-course-button')) world.scenario_dict['USER'] = get_user(name + '@edx.org')
def css_value(css_selector, index=0, max_attempts=5): # Wait for the css selector to appear if world.is_css_present(css_selector): return world.retry_on_exception(lambda: world.browser.find_by_css(css_selector)[index].value, max_attempts=max_attempts) else: return ""
def other_user_login(step, name): step.given('I log out') world.visit('/') signin_css = 'a.action-signin' world.is_css_present(signin_css) world.css_click(signin_css) def fill_login_form(): login_form = world.browser.find_by_css('form#login_form') login_form.find_by_name('email').fill(name + '@edx.org') login_form.find_by_name('password').fill("test") login_form.find_by_name('submit').click() world.retry_on_exception(fill_login_form) assert world.is_css_present('.new-course-button') world.scenario_dict['USER'] = get_user(name + '@edx.org')
def get_index(name): page_name_css = 'section[data-type="HTMLModule"]' all_pages = world.css_find(page_name_css) for i in range(len(all_pages)): if world.retry_on_exception(lambda: all_pages[i].html) == '\n {name}\n'.format(name=name): return i return None
def css_html(css_selector, index=0, max_attempts=5): """ Returns the HTML of a css_selector and will retry if there is a StaleElementReferenceException """ assert is_css_present(css_selector) return world.retry_on_exception( lambda: world.browser.find_by_css(css_selector)[index].html, max_attempts=max_attempts)
def get_setting_entry_index(label): 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 return world.retry_on_exception(get_index)
def get_setting_entry(label): 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 return world.retry_on_exception(get_setting)
def get_setting_entry_index(label): def get_index(): settings = world.css_find('.metadata_edit .wrapper-comp-setting') for index, setting in enumerate(settings): if setting.find_by_css('.setting-label')[0].value == label: return index return None return world.retry_on_exception(get_index)
def check_lti_iframe_content(text): # inside iframe test content is presented location = world.scenario_dict["LTI"].location.html_id() iframe_name = "ltiFrame-" + location with world.browser.get_iframe(iframe_name) as iframe: # iframe does not contain functions from terrain/ui_helpers.py assert iframe.is_element_present_by_css(".result", wait_time=0) assert text == world.retry_on_exception(lambda: iframe.find_by_css(".result")[0].text, max_attempts=5)
def assert_checked(problem_type, choices): ''' Assert that choice names given in *choices* are the only ones checked. Works for both radio and checkbox problems ''' all_choices = ['choice_0', 'choice_1', 'choice_2', 'choice_3'] for this_choice in all_choices: def check_problem(): element = world.css_find(inputfield(problem_type, choice=this_choice)) if this_choice in choices: assert element.checked else: assert not element.checked world.retry_on_exception(check_problem)
def other_user_login(step, name): step.given("I log out") world.visit("/") signin_css = "a.action-signin" world.is_css_present(signin_css) world.css_click(signin_css) def fill_login_form(): login_form = world.browser.find_by_css("form#login_form") login_form.find_by_name("email").fill(name + "@edx.org") login_form.find_by_name("password").fill("test") login_form.find_by_name("submit").click() world.retry_on_exception(fill_login_form) assert_true(world.is_css_present(".new-course-button")) world.scenario_dict["USER"] = get_user(name + "@edx.org")
def assert_checked(course, problem_type, choices): ''' Assert that choice names given in *choices* are the only ones checked. Works for both radio and checkbox problems ''' all_choices = ['choice_0', 'choice_1', 'choice_2', 'choice_3'] for this_choice in all_choices: def check_problem(): element = world.css_find(inputfield(course, problem_type, choice=this_choice)) if this_choice in choices: assert element.checked else: assert not element.checked world.retry_on_exception(check_problem)
def move_slider(self, step): r'I move the slider to the right$' handle_selector = '.gst-input .ui-slider-handle' world.wait_for_visible(handle_selector) world.wait_for_visible('.gst-value #value-display') 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()) world.retry_on_exception(try_move)
def check_lti_iframe_content(text): #inside iframe test content is presented location = world.scenario_dict['LTI'].location.html_id() iframe_name = 'ltiFrame-' + location with world.browser.get_iframe(iframe_name) as iframe: # iframe does not contain functions from terrain/ui_helpers.py assert iframe.is_element_present_by_css('.result', wait_time=0) assert (text == world.retry_on_exception( lambda: iframe.find_by_css('.result')[0].text, max_attempts=5))
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 log_into_studio(uname="robot", email="*****@*****.**", password="******"): world.browser.cookies.delete() world.visit("/") signin_css = "a.action-signin" world.is_css_present(signin_css) world.css_click(signin_css) def fill_login_form(): login_form = world.browser.find_by_css("form#login_form") login_form.find_by_name("email").fill(email) login_form.find_by_name("password").fill(password) login_form.find_by_name("submit").click() world.retry_on_exception(fill_login_form) assert_true(world.is_css_present(".new-course-button")) world.scenario_dict["USER"] = get_user_by_email(email)
def get_file(file_name): index = get_index(file_name) assert index != -1 url_css = 'a.filename' def get_url(): return world.css_find(url_css)[index]._element.get_attribute('href') url = world.retry_on_exception(get_url) return requests.get(url)
def add_a_multi_step_component(step, is_advanced, category): def click_advanced(): css = 'ul.problem-type-tabs a[href="#tab2"]' world.css_click(css) my_css = 'ul.problem-type-tabs li.ui-state-active a[href="#tab2"]' assert (world.css_find(my_css)) def find_matching_link(): """ Find the link with the specified text. There should be one and only one. """ # The tab shows links for the given category links = world.css_find('div.new-component-{} a'.format(category)) # Find the link whose text matches what you're looking for matched_links = [ link for link in links if link.text == step_hash['Component'] ] # There should be one and only one assert_equal(len(matched_links), 1) return matched_links[0] def click_link(): link.click() category = category.lower() for step_hash in step.hashes: css_selector = 'a[data-type="{}"]'.format(category) world.css_click(css_selector) world.wait_for_invisible(css_selector) if is_advanced: # Sometimes this click does not work if you go too fast. world.retry_on_exception(click_advanced, max_attempts=5, ignored_exceptions=AssertionError) # Retry this in case the list is empty because you tried too fast. link = world.retry_on_exception(func=find_matching_link, ignored_exceptions=AssertionError) # Wait for the link to be clickable. If you go too fast it is not. world.retry_on_exception(click_link)
def check_role(_step, role): world.is_css_present("iframe") location = world.scenario_dict["LTI"].location.html_id() iframe_name = "ltiFrame-" + location with world.browser.get_iframe(iframe_name) as iframe: expected_role = "Role: " + role role = world.retry_on_exception( lambda: iframe.find_by_tag("h5").first.value, max_attempts=5, ignored_exceptions=ElementDoesNotExist ) assert_equal(expected_role, role)
def click_component_from_menu(category, component_type, is_advanced): """ Creates a component for a category with more than one template, i.e. HTML and Problem. For some problem types, it is necessary to click to the Advanced tab. The component_type is the link text, e.g. "Blank Common Problem" """ if is_advanced: # Sometimes this click does not work if you go too fast. world.retry_on_exception(_click_advanced, ignored_exceptions=AssertionError) # Retry this in case the list is empty because you tried too fast. link = world.retry_on_exception( lambda: _find_matching_link(category, component_type), ignored_exceptions=AssertionError ) # Wait for the link to be clickable. If you go too fast it is not. world.retry_on_exception(lambda: link.click())
def check_role(_step, role): world.is_css_present('iframe') location = world.scenario_dict['LTI'].location.html_id() iframe_name = 'ltiFrame-' + location with world.browser.get_iframe(iframe_name) as iframe: expected_role = 'Role: ' + role role = world.retry_on_exception( lambda: iframe.find_by_tag('h5').first.value, max_attempts=5, ignored_exceptions=ElementDoesNotExist) assert_equal(expected_role, role)
def log_into_studio(uname='robot', email='*****@*****.**', password='******'): world.browser.cookies.delete() world.visit('/') signin_css = 'a.action-signin' world.is_css_present(signin_css) world.css_click(signin_css) def fill_login_form(): login_form = world.browser.find_by_css('form#login_form') login_form.find_by_name('email').fill(email) login_form.find_by_name('password').fill(password) login_form.find_by_name('submit').click() world.retry_on_exception(fill_login_form) assert_true(world.is_css_present('.new-course-button')) world.scenario_dict['USER'] = get_user_by_email(email)
def log_into_studio( uname='robot', email='*****@*****.**', password='******'): world.browser.cookies.delete() world.visit('/') signin_css = 'a.action-signin' world.is_css_present(signin_css) world.css_click(signin_css) def fill_login_form(): login_form = world.browser.find_by_css('form#login_form') login_form.find_by_name('email').fill(email) login_form.find_by_name('password').fill(password) login_form.find_by_name('submit').click() world.retry_on_exception(fill_login_form) assert_true(world.is_css_present('.new-course-button')) world.scenario_dict['USER'] = get_user_by_email(email)
def click_component_from_menu(category, component_type, is_advanced): """ Creates a component for a category with more than one template, i.e. HTML and Problem. For some problem types, it is necessary to click to the Advanced tab. The component_type is the link text, e.g. "Blank Common Problem" """ if is_advanced: # Sometimes this click does not work if you go too fast. world.retry_on_exception(_click_advanced, ignored_exceptions=AssertionError) # Retry this in case the list is empty because you tried too fast. link = world.retry_on_exception( lambda: _find_matching_link(category, component_type), ignored_exceptions=AssertionError) # Wait for the link to be clickable. If you go too fast it is not. world.retry_on_exception(lambda: link.click())
def check_role(_step, role): world.wait_for_present('iframe') location = world.scenario_dict['LTI'].location.html_id() iframe_name = 'ltiFrame-' + location with world.browser.get_iframe(iframe_name) as iframe: expected_role = 'Role: ' + role role = world.retry_on_exception( lambda: iframe.find_by_tag('h5').first.value, max_attempts=5, ignored_exceptions=ElementDoesNotExist ) assert_equal(expected_role, role)
def add_a_multi_step_component(step, is_advanced, category): def click_advanced(): css = 'ul.problem-type-tabs a[href="#tab2"]' world.css_click(css) my_css = 'ul.problem-type-tabs li.ui-state-active a[href="#tab2"]' assert(world.css_find(my_css)) def find_matching_link(): """ Find the link with the specified text. There should be one and only one. """ # The tab shows links for the given category links = world.css_find('div.new-component-{} a'.format(category)) # Find the link whose text matches what you're looking for matched_links = [link for link in links if link.text == step_hash['Component']] # There should be one and only one assert_equal(len(matched_links), 1) return matched_links[0] def click_link(): link.click() world.wait_for_xmodule() category = category.lower() for step_hash in step.hashes: css_selector = 'a[data-type="{}"]'.format(category) world.css_click(css_selector) world.wait_for_invisible(css_selector) if is_advanced: # Sometimes this click does not work if you go too fast. world.retry_on_exception(click_advanced, max_attempts=5, ignored_exceptions=AssertionError) # Retry this in case the list is empty because you tried too fast. link = world.retry_on_exception(func=find_matching_link, ignored_exceptions=AssertionError) # Wait for the link to be clickable. If you go too fast it is not. world.retry_on_exception(click_link)
def incorrect_lti_is_rendered(_step): # lti div has class rendered assert world.is_css_present('div.lti.rendered') # error is hidden assert not world.css_visible('.error_message') # iframe is visible assert world.css_visible('iframe') #inside iframe test content is presented with world.browser.get_iframe('ltiLaunchFrame') as iframe: # iframe does not contain functions from terrain/ui_helpers.py assert iframe.is_element_present_by_css('.result', wait_time=5) assert ("Wrong LTI signature" == world.retry_on_exception( lambda: iframe.find_by_css('.result')[0].text, max_attempts=5))
def incorrect_lti_is_rendered(_step): # lti div has class rendered assert world.is_css_present('div.lti.rendered') # error is hidden assert not world.css_visible('.error_message') # iframe is visible assert world.css_visible('iframe') #inside iframe test content is presented with world.browser.get_iframe('ltiLaunchFrame') as iframe: # iframe does not contain functions from terrain/ui_helpers.py assert iframe.is_element_present_by_css('.result', wait_time=5) assert ("Wrong LTI signature" == world.retry_on_exception( lambda: iframe.find_by_css('.result')[0].text, max_attempts=5 ))
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 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 answer_problem(course, problem_type, correctness): # Make sure that the problem has been completely rendered before # starting to input an answer. world.wait_for_ajax_complete() section_loc = section_location(course) if problem_type == "drop down": select_name = "input_{}_2_1".format( section_loc.course_key.make_usage_key('problem', 'drop_down').html_id()) option_text = 'Option 2' if correctness == 'correct' else 'Option 3' world.select_option(select_name, option_text) elif problem_type == "multiple choice": if correctness == 'correct': world.css_check( inputfield(course, 'multiple choice', choice='choice_2')) else: world.css_check( inputfield(course, 'multiple choice', choice='choice_1')) elif problem_type == "checkbox": if correctness == 'correct': world.css_check(inputfield(course, 'checkbox', choice='choice_0')) world.css_check(inputfield(course, 'checkbox', choice='choice_2')) else: world.css_check(inputfield(course, 'checkbox', choice='choice_3')) elif problem_type == 'radio': if correctness == 'correct': world.css_check(inputfield(course, 'radio', choice='choice_2')) else: world.css_check(inputfield(course, 'radio', choice='choice_1')) elif problem_type == 'string': textvalue = 'correct string' if correctness == 'correct' else 'incorrect' world.css_fill(inputfield(course, 'string'), textvalue) elif problem_type == 'numerical': textvalue = "pi + 1" if correctness == 'correct' else str( random.randint(-2, 2)) world.css_fill(inputfield(course, 'numerical'), textvalue) elif problem_type == 'formula': textvalue = "x^2+2*x+y" if correctness == 'correct' else 'x^2' world.css_fill(inputfield(course, 'formula'), textvalue) elif problem_type == 'script': # Correct answer is any two integers that sum to 10 first_addend = random.randint(-100, 100) second_addend = 10 - first_addend # If we want an incorrect answer, then change # the second addend so they no longer sum to 10 if correctness == 'incorrect': second_addend += random.randint(1, 10) world.css_fill(inputfield(course, 'script', input_num=1), str(first_addend)) world.css_fill(inputfield(course, 'script', input_num=2), str(second_addend)) elif problem_type == 'code': # The fake xqueue server is configured to respond # correct / incorrect no matter what we submit. # Furthermore, since the inline code response uses # JavaScript to make the code display nicely, it's difficult # to programatically input text # (there's not <textarea> we can just fill text into) # For this reason, we submit the initial code in the response # (configured in the problem XML above) pass elif problem_type == 'radio_text' or problem_type == 'checkbox_text': input_value = "8" if correctness == 'correct' else "5" choice = "choiceinput_0bc" if correctness == 'correct' else "choiceinput_1bc" world.css_fill( inputfield(course, problem_type, choice="choiceinput_0_numtolerance_input_0"), input_value) world.css_check(inputfield(course, problem_type, choice=choice)) elif problem_type == 'image': offset = 25 if correctness == "correct" else -25 def try_click(): problem_html_loc = section_loc.course_key.make_usage_key( 'problem', 'image').html_id() image_selector = "#imageinput_{}_2_1".format(problem_html_loc) input_selector = "#input_{}_2_1".format(problem_html_loc) world.browser.execute_script( '$("body").on("click", function(event) {console.log(event);})') initial_input = world.css_value(input_selector) world.wait_for_visible(image_selector) image = world.css_find(image_selector).first (image.action_chains.move_to_element( image._element).move_by_offset(offset, offset).click().perform()) world.wait_for( lambda _: world.css_value(input_selector) != initial_input) world.retry_on_exception(try_click)
def i_press_the_button_on_the_registration_form(step): def submit_registration(): register_form = world.browser.find_by_css('form#register-form') register_form.find_by_name('submit').click() world.retry_on_exception(submit_registration)
def click_link(partial_text, index=0, max_attempts=5): return world.retry_on_exception(lambda: world.browser.find_link_by_partial_text(partial_text)[index].click(), max_attempts=max_attempts)
def css_fill(css_selector, text, index=0, max_attempts=5): assert is_css_present(css_selector) return world.retry_on_exception(lambda: world.browser.find_by_css(css_selector)[index].fill(text), max_attempts=max_attempts)
def when_i_fill_in_field_on_the_registration_form_with_value(step, field, value): def fill_in_registration(): register_form = world.browser.find_by_css('form#register-form') form_field = register_form.find_by_name(field) form_field.fill(value) world.retry_on_exception(fill_in_registration)
def css_has_class(css_selector, class_name, index=0, max_attempts=5): return world.retry_on_exception(lambda: world.css_find(css_selector)[index].has_class(class_name), max_attempts=max_attempts)
def answer_problem(course, problem_type, correctness): # Make sure that the problem has been completely rendered before # starting to input an answer. world.wait_for_ajax_complete() section_loc = section_location(course) if problem_type == "drop down": select_name = "input_{}_2_1".format( section_loc.course_key.make_usage_key('problem', 'drop_down').html_id() ) option_text = 'Option 2' if correctness == 'correct' else 'Option 3' world.select_option(select_name, option_text) elif problem_type == "multiple choice": if correctness == 'correct': world.css_check(inputfield(course, 'multiple choice', choice='choice_2')) else: world.css_check(inputfield(course, 'multiple choice', choice='choice_1')) elif problem_type == "checkbox": if correctness == 'correct': world.css_check(inputfield(course, 'checkbox', choice='choice_0')) world.css_check(inputfield(course, 'checkbox', choice='choice_2')) else: world.css_check(inputfield(course, 'checkbox', choice='choice_3')) elif problem_type == 'radio': if correctness == 'correct': world.css_check(inputfield(course, 'radio', choice='choice_2')) else: world.css_check(inputfield(course, 'radio', choice='choice_1')) elif problem_type == 'string': textvalue = 'correct string' if correctness == 'correct' else 'incorrect' world.css_fill(inputfield(course, 'string'), textvalue) elif problem_type == 'numerical': textvalue = "pi + 1" if correctness == 'correct' else str(random.randint(-2, 2)) world.css_fill(inputfield(course, 'numerical'), textvalue) elif problem_type == 'formula': textvalue = "x^2+2*x+y" if correctness == 'correct' else 'x^2' world.css_fill(inputfield(course, 'formula'), textvalue) elif problem_type == 'script': # Correct answer is any two integers that sum to 10 first_addend = random.randint(-100, 100) second_addend = 10 - first_addend # If we want an incorrect answer, then change # the second addend so they no longer sum to 10 if correctness == 'incorrect': second_addend += random.randint(1, 10) world.css_fill(inputfield(course, 'script', input_num=1), str(first_addend)) world.css_fill(inputfield(course, 'script', input_num=2), str(second_addend)) elif problem_type == 'code': # The fake xqueue server is configured to respond # correct / incorrect no matter what we submit. # Furthermore, since the inline code response uses # JavaScript to make the code display nicely, it's difficult # to programatically input text # (there's not <textarea> we can just fill text into) # For this reason, we submit the initial code in the response # (configured in the problem XML above) pass elif problem_type == 'radio_text' or problem_type == 'checkbox_text': input_value = "8" if correctness == 'correct' else "5" choice = "choiceinput_0bc" if correctness == 'correct' else "choiceinput_1bc" world.css_fill( inputfield( course, problem_type, choice="choiceinput_0_numtolerance_input_0" ), input_value ) world.css_check(inputfield(course, problem_type, choice=choice)) elif problem_type == 'image': offset = 25 if correctness == "correct" else -25 def try_click(): problem_html_loc = section_loc.course_key.make_usage_key('problem', 'image').html_id() image_selector = "#imageinput_{}_2_1".format(problem_html_loc) input_selector = "#input_{}_2_1".format(problem_html_loc) world.browser.execute_script('$("body").on("click", function(event) {console.log(event);})') initial_input = world.css_value(input_selector) world.wait_for_visible(image_selector) image = world.css_find(image_selector).first (image.action_chains .move_to_element(image._element) .move_by_offset(offset, offset) .click() .perform()) world.wait_for(lambda _: world.css_value(input_selector) != initial_input) world.retry_on_exception(try_click)
def css_visible(css_selector, index=0, max_attempts=5): assert is_css_present(css_selector) return world.retry_on_exception(lambda: world.browser.find_by_css(css_selector)[index].visible, max_attempts=max_attempts)