예제 #1
0
def xml_only_video(step):
    # Create a new video *without* metadata. This requires a certain
    # amount of rummaging to make sure all the correct data is present
    step.given('I have clicked the new unit button')

    # Wait for the new unit to be created and to load the page
    world.wait(1)

    course = world.scenario_dict['COURSE']
    store = get_modulestore(course.location)

    parent_location = store.get_items(course.id, category='vertical', revision='draft')[0].location

    youtube_id = 'ABCDEFG'
    world.scenario_dict['YOUTUBE_ID'] = youtube_id

    # Create a new Video component, but ensure that it doesn't have
    # metadata. This allows us to test that we are correctly parsing
    # out XML
    world.ItemFactory.create(
        parent_location=parent_location,
        category='video',
        data='<video youtube="1.00:%s"></video>' % youtube_id,
        modulestore=store,
    )
예제 #2
0
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)
예제 #3
0
def other_delete_self(_step):
    to_delete_css = '.user-item .item-actions a.remove-user[data-id="{email}"]'.format(
        email="*****@*****.**")
    world.css_click(to_delete_css)
    # confirm prompt
    world.wait(.5)
    world.css_click(".wrapper-prompt-warning .action-primary")
예제 #4
0
def other_delete_self(_step):
    to_delete_css = '.user-item .item-actions a.remove-user[data-id="{email}"]'.format(
        email="*****@*****.**")
    world.css_click(to_delete_css)
    # confirm prompt
    world.wait(.5)
    world.css_click(".wrapper-prompt-warning .action-primary")
예제 #5
0
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')
예제 #6
0
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")
예제 #7
0
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)
예제 #8
0
def wait_for_js_variable_truthy(variable):
    """
    Using Selenium's `execute_async_script` function, poll the Javascript
    enviornment until the given variable is defined and truthy. This process
    guards against page reloads, and seamlessly retries on the next page.
    """
    js = """
        var callback = arguments[arguments.length - 1];
        var unloadHandler = function() {{
          callback("unload");
        }}
        addEventListener("beforeunload", unloadHandler);
        addEventListener("unload", unloadHandler);
        var intervalID = setInterval(function() {{
          try {{
            if({variable}) {{
              clearInterval(intervalID);
              removeEventListener("beforeunload", unloadHandler);
              removeEventListener("unload", unloadHandler);
              callback(true);
            }}
          }} catch (e) {{}}
        }}, 10);
    """.format(variable=variable)
    for _ in range(5):  # 5 attempts max
        result = world.browser.driver.execute_async_script(dedent(js))
        if result == "unload":
            # we ran this on the wrong page. Wait a bit, and try again, when the
            # browser has loaded the next page.
            world.wait(1)
            continue
        else:
            return result
예제 #9
0
def wait_for_ajax_complete():
    """
    Wait until all jQuery AJAX calls have completed. "Complete" means that
    either the server has sent a response (regardless of whether the response
    indicates success or failure), or that the AJAX call timed out waiting for
    a response. For more information about the `jQuery.active` counter that
    keeps track of this information, go here:
    http://stackoverflow.com/questions/3148225/jquery-active-function#3148506
    """
    javascript = """
        var callback = arguments[arguments.length - 1];
        if(!window.jQuery) {callback(false);}
        var intervalID = setInterval(function() {
          if(jQuery.active == 0) {
            clearInterval(intervalID);
            callback(true);
          }
        }, 100);
    """
    # Sometimes the ajax when it returns will make the browser reload
    # the DOM, and throw a WebDriverException with the message:
    # 'javascript error: document unloaded while waiting for result'
    for _ in range(5):  # 5 attempts max
        try:
            result = world.browser.driver.execute_async_script(dedent(javascript))
        except WebDriverException as wde:
            if "document unloaded while waiting for result" in wde.msg:
                # Wait a bit, and try again, when the browser has reloaded the page.
                world.wait(1)
                continue
            else:
                raise
        return result
예제 #10
0
def see_section_content(step, section):
    world.wait(0.5)
    if section == "2":
        text = 'The correct answer is Option 2'
    elif section == "1":
        text = 'The correct answer is Choice 3'
    step.given('I should see "' + text + '" somewhere on the page')
예제 #11
0
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")
예제 #12
0
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
예제 #13
0
def xml_only_video(step):
    # Create a new video *without* metadata. This requires a certain
    # amount of rummaging to make sure all the correct data is present
    step.given("I have clicked the new unit button")

    # Wait for the new unit to be created and to load the page
    world.wait(1)

    course = world.scenario_dict["COURSE"]
    store = get_modulestore(course.location)

    parent_location = store.get_items(course.id, category="vertical", revision="draft")[0].location

    youtube_id = "ABCDEFG"
    world.scenario_dict["YOUTUBE_ID"] = youtube_id

    # Create a new Video component, but ensure that it doesn't have
    # metadata. This allows us to test that we are correctly parsing
    # out XML
    world.ItemFactory.create(
        parent_location=parent_location,
        category="video",
        data='<video youtube="1.00:%s"></video>' % youtube_id,
        modulestore=store,
    )
예제 #14
0
def xml_only_video(step):
    # Create a new video *without* metadata. This requires a certain
    # amount of rummaging to make sure all the correct data is present
    step.given('I have clicked the new unit button')

    # Wait for the new unit to be created and to load the page
    world.wait(1)

    location = world.scenario_dict['COURSE'].location
    store = get_modulestore(location)

    parent_location = store.get_items(Location(category='vertical', revision='draft'))[0].location

    youtube_id = 'ABCDEFG'
    world.scenario_dict['YOUTUBE_ID'] = youtube_id

    # Create a new Video component, but ensure that it doesn't have
    # metadata. This allows us to test that we are correctly parsing
    # out XML
    video = world.ItemFactory.create(
        parent_location=parent_location,
        category='video',
        data='<video youtube="1.00:%s"></video>' % youtube_id
    )

    # Refresh to see the new video
    reload_the_page(step)
예제 #15
0
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)
예제 #16
0
def xml_only_video(step):
    # Create a new video *without* metadata. This requires a certain
    # amount of rummaging to make sure all the correct data is present
    step.given('I have clicked the new unit button')

    # Wait for the new unit to be created and to load the page
    world.wait(1)

    course = world.scenario_dict['COURSE']
    store = modulestore()

    parent_location = store.get_items(course.id, qualifiers={'category': 'vertical'})[0].location

    youtube_id = 'ABCDEFG'
    world.scenario_dict['YOUTUBE_ID'] = youtube_id

    # Create a new Video component, but ensure that it doesn't have
    # metadata. This allows us to test that we are correctly parsing
    # out XML
    world.ItemFactory.create(
        parent_location=parent_location,
        category='video',
        data='<video youtube="1.00:%s"></video>' % youtube_id,
        modulestore=store,
        user_id=world.scenario_dict["USER"].id
    )
예제 #17
0
def delete_other_user(_step, name):
    to_delete_css = '.user-item .item-actions a.remove-user[data-id="{email}"]'.format(
        email="{0}{1}".format(name, EMAIL_EXTENSION))
    world.css_click(to_delete_css)
    # confirm prompt
    # need to wait for the animation to be done, there isn't a good success condition that won't work both on latest chrome and jenkins
    world.wait(.5)
    world.css_click(".wrapper-prompt-warning .action-primary")
예제 #18
0
def delete_other_user(_step, name):
    to_delete_css = '.user-item .item-actions a.remove-user[data-id="{email}"]'.format(
        email="{0}{1}".format(name, '@edx.org'))
    world.css_click(to_delete_css)
    # confirm prompt
    # need to wait for the animation to be done, there isn't a good success condition that won't work both on latest chrome and jenkins
    world.wait(.5)
    world.css_click(".wrapper-prompt-warning .action-primary")
예제 #19
0
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)
예제 #20
0
def i_select_advanced_settings(step):
    world.click_course_settings()
    link_css = 'li.nav-course-settings-advanced a'
    world.css_click(link_css)
    world.wait_for_requirejs(
        ["jquery", "js/models/course", "js/models/settings/advanced",
         "js/views/settings/advanced", "codemirror"])
    # this shouldn't be necessary, but we experience sporadic failures otherwise
    world.wait(1)
예제 #21
0
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')
예제 #22
0
def see_a_range_slider_with_proper_range(_step, left, width):
    left = int(left.strip())
    width = int(width.strip())

    world.wait_for_visible(".slider-range")
    world.wait(4)
    slider_range = world.browser.driver.find_element_by_css_selector(".slider-range")

    assert int(round(float(slider_range.value_of_css_property("left")[:-2]))) == left
    assert int(round(float(slider_range.value_of_css_property("width")[:-2]))) == width
예제 #23
0
def i_select_advanced_settings(step):
    world.click_course_settings()
    link_css = 'li.nav-course-settings-advanced a'
    world.css_click(link_css)
    world.wait_for_requirejs([
        "jquery", "js/models/course", "js/models/settings/advanced",
        "js/views/settings/advanced", "codemirror"
    ])
    # this shouldn't be necessary, but we experience sporadic failures otherwise
    world.wait(1)
예제 #24
0
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()
예제 #25
0
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])
예제 #26
0
def see_a_range_slider_with_proper_range(_step, left, width):
    left = int(left.strip())
    width = int(width.strip())

    world.wait_for_visible(".slider-range")
    world.wait(4)
    slider_range = world.browser.driver.find_element_by_css_selector(".slider-range")

    assert int(round(float(slider_range.value_of_css_property("left")[:-2]))) == left
    assert int(round(float(slider_range.value_of_css_property("width")[:-2]))) == width
예제 #27
0
def i_created_a_video_component(step):
    world.create_course_with_unit()
    world.create_component_instance(step=step, category="video")

    world.wait_for_xmodule()
    world.disable_jquery_animations()

    world.wait_for_present(".is-initialized")
    world.wait(DELAY)
    world.wait_for_invisible(SELECTORS["spinner"])
예제 #28
0
def delete_file(_step, file_name):
    index = get_index(file_name)
    assert index != -1
    delete_css = "a.remove-asset-button"
    world.css_click(delete_css, index=index)

    world.wait_for_present(".wrapper-prompt.is-shown")
    world.wait(0.2)  # wait for css animation
    prompt_confirm_css = 'li.nav-item > a.action-primary'
    world.css_click(prompt_confirm_css)
예제 #29
0
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()
예제 #30
0
def check_captions_visibility_state(_step, visibility_state, timeout):
    timeout = int(timeout.strip())

    # Captions become invisible by fading out. We must wait by a specified
    # time.
    world.wait(timeout)

    if visibility_state == 'visible':
        assert world.css_visible('.subtitles')
    else:
        assert not world.css_visible('.subtitles')
예제 #31
0
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()
예제 #32
0
def check_captions_visibility_state(_step, visibility_state, timeout):
    timeout = int(timeout.strip())

    # Captions become invisible by fading out. We must wait by a specified
    # time.
    world.wait(timeout)

    if visibility_state == "visible":
        assert world.css_visible(".subtitles")
    else:
        assert not world.css_visible(".subtitles")
예제 #33
0
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()
예제 #34
0
def shows_captions(_step, show_captions):
    world.wait_for_js_variable_truthy("Video")
    world.wait(0.5)
    if show_captions == 'does not':
        assert_true(world.is_css_present('div.video.closed'))
    else:
        assert_true(world.is_css_not_present('div.video.closed'))

    # Prevent cookies from overriding course settings
    world.browser.cookies.delete('hide_captions')
    world.browser.cookies.delete('current_player_mode')
예제 #35
0
def add_other_user(_step, name):
    new_user_css = 'a.create-user-button'
    world.css_click(new_user_css)
    world.wait(0.5)

    email_css = 'input#user-email-input'
    f = world.css_find(email_css)
    f._element.send_keys(name, EMAIL_EXTENSION)

    confirm_css = 'form.create-user button.action-primary'
    world.css_click(confirm_css)
예제 #36
0
def shows_captions(_step, show_captions):
    world.wait_for_js_variable_truthy("Video")
    world.wait(0.5)
    if show_captions == 'does not':
        assert_true(world.is_css_present('div.video.closed'))
    else:
        assert_true(world.is_css_not_present('div.video.closed'))

    # Prevent cookies from overriding course settings
    world.browser.cookies.delete('hide_captions')
    world.browser.cookies.delete('current_player_mode')
예제 #37
0
def add_other_user(_step, name):
    new_user_css = 'a.create-user-button'
    world.css_click(new_user_css)
    world.wait(0.5)

    email_css = 'input#user-email-input'
    world.css_fill(email_css, name + EMAIL_EXTENSION)
    if world.is_firefox():
        world.trigger_event(email_css)
    confirm_css = 'form.create-user button.action-primary'
    world.css_click(confirm_css)
예제 #38
0
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".')
예제 #39
0
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".')
예제 #40
0
def shows_captions(_step, show_captions):
    world.wait_for_js_variable_truthy("Video")
    world.wait(0.5)
    if show_captions == "does not":
        assert world.is_css_present("div.video.closed")
    else:
        assert world.is_css_not_present("div.video.closed")

    # Prevent cookies from overriding course settings
    world.browser.cookies.delete("hide_captions")
    world.browser.cookies.delete("current_player_mode")
예제 #41
0
def add_other_user(_step, name):
    new_user_css = 'a.create-user-button'
    world.css_click(new_user_css)
    world.wait(0.5)

    email_css = 'input#user-email-input'
    world.css_fill(email_css, name + '@edx.org')
    if world.is_firefox():
        world.trigger_event(email_css)
    confirm_css = 'form.create-user button.action-primary'
    world.css_click(confirm_css)
예제 #42
0
def load_requrejs_modules(dependencies, callback="callback(true);"):
    javascript = """
        var callback = arguments[arguments.length - 1];
        if(window.require) {{
          requirejs.onError = callback;
          var unloadHandler = function() {{
            callback("unload");
          }}
          addEventListener("beforeunload", unloadHandler);
          addEventListener("unload", unloadHandler);
          require({deps}, function($) {{
            var modules = arguments;
            setTimeout(function() {{
              removeEventListener("beforeunload", unloadHandler);
              removeEventListener("unload", unloadHandler);
              {callback}
            }}, 50);
          }});
        }} else {{
          callback(false);
        }}
    """.format(deps=json.dumps(dependencies), callback=callback)
    for _ in range(5):  # 5 attempts max
        try:
            result = world.browser.driver.execute_async_script(
                dedent(javascript))
        except WebDriverException as wde:
            if "document unloaded while waiting for result" in wde.msg:
                result = "unload"
            else:
                raise
        if result == "unload":
            # we ran this on the wrong page. Wait a bit, and try again, when the
            # browser has loaded the next page.
            world.wait(1)
            continue
        elif result not in (None, True, False):
            # We got a require.js error
            # Sometimes requireJS will throw an error with requireType=require
            # This doesn't seem to cause problems on the page, so we ignore it
            if result['requireType'] == 'require':
                world.wait(1)
                continue

            # Otherwise, fail and report the error
            else:
                msg = "Error loading dependencies: type={0} modules={1}".format(
                    result['requireType'], result['requireModules'])
                err = RequireJSError(msg)
                err.error = result
                raise err
        else:
            return result
예제 #43
0
def css_text(css_selector):

    # Wait for the css selector to appear
    if world.is_css_present(css_selector):
        try:
            return world.browser.find_by_css(css_selector).first.text
        except StaleElementReferenceException:
            # The DOM was still redrawing. Wait a second and try again.
            world.wait(1)
            return world.browser.find_by_css(css_selector).first.text
    else:
        return ""
예제 #44
0
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)
예제 #45
0
def retry_on_exception(func, max_attempts=5):
    attempt = 0
    while attempt < max_attempts:
        try:
            return func()
            break
        except WebDriverException:
            world.wait(1)
            attempt += 1
        except:
            attempt += 1
    assert_true(attempt < max_attempts, 'Ran out of attempts to execute {}'.format(func))
예제 #46
0
def i_created_a_video_component(step):
    world.create_course_with_unit()
    world.create_component_instance(
        step=step,
        category='video',
    )

    world.wait_for_xmodule()
    world.disable_jquery_animations()

    world.wait_for_present('.is-initialized')
    world.wait(DELAY)
    world.wait_for_invisible(SELECTORS['spinner'])
예제 #47
0
def css_click(css_selector):
    """
    Perform a click on a CSS selector, retrying if it initially fails
    """
    try:
        world.browser.find_by_css(css_selector).click()

    except WebDriverException:
        # Occassionally, MathJax or other JavaScript can cover up
        # an element  temporarily.
        # If this happens, wait a second, then try again
        world.wait(1)
        world.browser.find_by_css(css_selector).click()
예제 #48
0
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()
예제 #49
0
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()
예제 #50
0
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')
예제 #51
0
def i_created_a_video_component(step):
    step.given('I am in Studio editing a new unit')
    world.create_component_instance(
        step=step,
        category='video',
    )

    world.wait_for_xmodule()
    world.disable_jquery_animations()

    world.wait_for_present('.is-initialized')
    world.wait(DELAY)
    world.wait_for_invisible(SELECTORS['spinner'])
    if not world.youtube.config.get('youtube_api_blocked'):
        world.wait_for_visible(SELECTORS['controls'])
예제 #52
0
def retry_on_exception(func, max_attempts=5, ignored_exceptions=(StaleElementReferenceException, InvalidElementStateException)):
    """
    Retry the interaction, ignoring the passed exceptions.
    By default ignore StaleElementReferenceException, which happens often in our application
    when the DOM is being manipulated by client side JS.
    Note that ignored_exceptions is passed directly to the except block, and as such can be
    either a single exception or multiple exceptions as a parenthesized tuple.
    """
    attempt = 0
    while attempt < max_attempts:
        try:
            return func()
        except ignored_exceptions:
            world.wait(1)
            attempt += 1

    assert_true(attempt < max_attempts, 'Ran out of attempts to execute {}'.format(func))
예제 #53
0
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()
    world.disable_jquery_animations()

    world.wait_for_present('.is-initialized')
    world.wait(DELAY)
    assert not world.css_visible(SELECTORS['spinner'])
예제 #54
0
파일: video.py 프로젝트: qbig/edx-platform
def i_created_a_video_component(_step):

    assert_less(world.youtube.config['youtube_api_response'].status_code, 400,
                "Real Youtube server is unavailable")

    world.create_course_with_unit()
    world.create_component_instance(
        step=_step,
        category='video',
    )

    world.wait_for_xmodule()
    world.disable_jquery_animations()

    world.wait_for_present('.is-initialized')
    world.wait(DELAY)
    world.wait_for_invisible(SELECTORS['spinner'])
    if not world.youtube.config.get('youtube_api_blocked'):
        world.wait_for_visible(SELECTORS['controls'])
예제 #55
0
def wait_for_js_variable_truthy(variable):
    """
    Using Selenium's `execute_async_script` function, poll the Javascript
    environment until the given variable is defined and truthy. This process
    guards against page reloads, and seamlessly retries on the next page.
    """
    javascript = """
        var callback = arguments[arguments.length - 1];
        var unloadHandler = function() {{
          callback("unload");
        }}
        addEventListener("beforeunload", unloadHandler);
        addEventListener("unload", unloadHandler);
        var intervalID = setInterval(function() {{
          try {{
            if({variable}) {{
              clearInterval(intervalID);
              removeEventListener("beforeunload", unloadHandler);
              removeEventListener("unload", unloadHandler);
              callback(true);
            }}
          }} catch (e) {{}}
        }}, 10);
    """.format(variable=variable)
    for _ in range(5):  # 5 attempts max
        try:
            result = world.browser.driver.execute_async_script(
                dedent(javascript))
        except WebDriverException as wde:
            if "document unloaded while waiting for result" in wde.msg:
                result = "unload"
            else:
                raise
        if result == "unload":
            # we ran this on the wrong page. Wait a bit, and try again, when the
            # browser has loaded the next page.
            world.wait(1)
            continue
        else:
            return result
예제 #56
0
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])