Merge pull request #594 from edx/jonahstanley/firefox-acceptance-tests
Jonahstanley/firefox acceptance tests
This commit is contained in:
@@ -40,6 +40,7 @@ Feature: Advanced (manual) course policy
|
||||
And I reload the page
|
||||
Then the policy key value is unchanged
|
||||
|
||||
# This feature will work in Firefox only when Firefox is the active window
|
||||
Scenario: Test automatic quoting of non-JSON values
|
||||
Given I am on the Advanced Course Settings page in Studio
|
||||
When I create a non-JSON value not in quotes
|
||||
|
||||
@@ -10,6 +10,7 @@ Feature: Course checklists
|
||||
Then I can check and uncheck tasks in a checklist
|
||||
And They are correctly selected after reloading the page
|
||||
|
||||
# CHROME ONLY, due to issues getting link to be active in firefox
|
||||
Scenario: A task can link to a location within Studio
|
||||
Given I have opened Checklists
|
||||
When I select a link to the course outline
|
||||
@@ -17,6 +18,7 @@ Feature: Course checklists
|
||||
And I press the browser back button
|
||||
Then I am brought back to the course outline in the correct state
|
||||
|
||||
# CHROME ONLY, due to issues getting link to be active in firefox
|
||||
Scenario: A task can link to a location outside Studio
|
||||
Given I have opened Checklists
|
||||
When I select a link to help page
|
||||
|
||||
@@ -70,8 +70,12 @@ def press_the_notification_button(_step, name):
|
||||
confirmation_dismissed = world.is_css_not_present('.is-shown.wrapper-notification-warning')
|
||||
error_showing = world.is_css_present('.is-shown.wrapper-notification-error')
|
||||
return confirmation_dismissed or error_showing
|
||||
|
||||
world.css_click(css, success_condition=button_clicked), '%s button not clicked after 5 attempts.' % name
|
||||
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(css, event='focus')
|
||||
world.browser.execute_script("$('{}').click()".format(css))
|
||||
else:
|
||||
world.css_click(css, success_condition=button_clicked), '%s button not clicked after 5 attempts.' % name
|
||||
|
||||
|
||||
@step('I change the "(.*)" field to "(.*)"$')
|
||||
@@ -230,7 +234,7 @@ def i_created_video_alpha(step):
|
||||
def i_enabled_the_advanced_module(step, module):
|
||||
step.given('I have opened a new course section in Studio')
|
||||
world.css_click('.nav-course-settings')
|
||||
world.css_click('.nav-course-settings-advanced')
|
||||
world.css_click('.nav-course-settings-advanced a')
|
||||
type_in_codemirror(0, '["%s"]' % module)
|
||||
press_the_notification_button(step, 'Save')
|
||||
|
||||
@@ -272,7 +276,7 @@ def i_am_shown_a_notification(step, notification_type):
|
||||
|
||||
|
||||
def type_in_codemirror(index, text):
|
||||
world.css_click(".CodeMirror", index=index)
|
||||
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():
|
||||
@@ -281,3 +285,5 @@ def type_in_codemirror(index, text):
|
||||
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')
|
||||
|
||||
@@ -56,7 +56,7 @@ def click_component_from_menu(category, boilerplate, expected_css):
|
||||
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')
|
||||
world.css_click('#settings-mode a')
|
||||
|
||||
|
||||
@world.absorb
|
||||
@@ -114,8 +114,20 @@ def revert_setting_entry(label):
|
||||
|
||||
@world.absorb
|
||||
def get_setting_entry(label):
|
||||
settings = world.browser.find_by_css('.wrapper-comp-setting')
|
||||
for setting in settings:
|
||||
if setting.find_by_css('.setting-label')[0].value == label:
|
||||
return setting
|
||||
return None
|
||||
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)
|
||||
|
||||
@world.absorb
|
||||
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)
|
||||
|
||||
@@ -15,6 +15,8 @@ Feature: Course Team
|
||||
And I am viewing the course team settings
|
||||
When I add "bob" to the course team
|
||||
And "bob" logs in
|
||||
And he selects the new course
|
||||
And he views the course team settings
|
||||
Then he cannot delete users
|
||||
And he cannot add users
|
||||
|
||||
|
||||
@@ -42,9 +42,9 @@ def add_other_user(_step, name):
|
||||
world.wait(0.5)
|
||||
|
||||
email_css = 'input#user-email-input'
|
||||
f = world.css_find(email_css)
|
||||
f._element.send_keys(name, EMAIL_EXTENSION)
|
||||
|
||||
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)
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ from common import type_in_codemirror
|
||||
@step(u'I go to the course updates page')
|
||||
def go_to_updates(_step):
|
||||
menu_css = 'li.nav-course-courseware'
|
||||
updates_css = 'li.nav-course-courseware-updates'
|
||||
updates_css = 'li.nav-course-courseware-updates a'
|
||||
world.css_click(menu_css)
|
||||
world.css_click(updates_css)
|
||||
|
||||
|
||||
@@ -47,12 +47,12 @@ Feature: Problem Editor
|
||||
Scenario: User cannot type decimal values integer number field
|
||||
Given I have created a Blank Common Problem
|
||||
When I edit and select Settings
|
||||
Then if I set the max attempts to "2.34", it displays initially as "234", and is persisted as "234"
|
||||
Then if I set the max attempts to "2.34", it will persist as a valid integer
|
||||
|
||||
Scenario: User cannot type out of range values in an integer number field
|
||||
Given I have created a Blank Common Problem
|
||||
When I edit and select Settings
|
||||
Then if I set the max attempts to "-3", it displays initially as "-3", and is persisted as "0"
|
||||
Then if I set the max attempts to "-3", it will persist as a valid integer
|
||||
|
||||
Scenario: Settings changes are not saved on Cancel
|
||||
Given I have created a Blank Common Problem
|
||||
@@ -66,6 +66,7 @@ Feature: Problem Editor
|
||||
When I edit and select Settings
|
||||
Then Edit High Level Source is visible
|
||||
|
||||
# This feature will work in Firefox only when Firefox is the active window
|
||||
Scenario: High Level source is persisted for LaTeX problem (bug STUD-280)
|
||||
Given I have created a LaTeX Problem
|
||||
When I edit and compile the High Level Source
|
||||
|
||||
@@ -45,7 +45,10 @@ def i_see_five_settings_with_values(step):
|
||||
def i_can_modify_the_display_name(step):
|
||||
# Verifying that the display name can be a string containing a floating point value
|
||||
# (to confirm that we don't throw an error because it is of the wrong type).
|
||||
world.get_setting_entry(DISPLAY_NAME).find_by_css('.setting-input')[0].fill('3.4')
|
||||
index = world.get_setting_entry_index(DISPLAY_NAME)
|
||||
world.css_fill('.wrapper-comp-setting .setting-input', '3.4', index=index)
|
||||
if world.is_firefox():
|
||||
world.trigger_event('.wrapper-comp-setting .setting-input', index=index)
|
||||
verify_modified_display_name()
|
||||
|
||||
|
||||
@@ -57,7 +60,10 @@ def my_display_name_change_is_persisted_on_save(step):
|
||||
|
||||
@step('I can specify special characters in the display name')
|
||||
def i_can_modify_the_display_name_with_special_chars(step):
|
||||
world.get_setting_entry(DISPLAY_NAME).find_by_css('.setting-input')[0].fill("updated ' \" &")
|
||||
index = world.get_setting_entry_index(DISPLAY_NAME)
|
||||
world.css_fill('.wrapper-comp-setting .setting-input', "updated ' \" &", index=index)
|
||||
if world.is_firefox():
|
||||
world.trigger_event('.wrapper-comp-setting .setting-input', index=index)
|
||||
verify_modified_display_name_with_special_chars()
|
||||
|
||||
|
||||
@@ -127,12 +133,16 @@ def set_the_weight_to_abc(step, bad_weight):
|
||||
world.verify_setting_entry(world.get_setting_entry(PROBLEM_WEIGHT), PROBLEM_WEIGHT, "", False)
|
||||
|
||||
|
||||
@step('if I set the max attempts to "(.*)", it displays initially as "(.*)", and is persisted as "(.*)"')
|
||||
def set_the_max_attempts(step, max_attempts_set, max_attempts_displayed, max_attempts_persisted):
|
||||
world.get_setting_entry(MAXIMUM_ATTEMPTS).find_by_css('.setting-input')[0].fill(max_attempts_set)
|
||||
world.verify_setting_entry(world.get_setting_entry(MAXIMUM_ATTEMPTS), MAXIMUM_ATTEMPTS, max_attempts_displayed, True)
|
||||
@step('if I set the max attempts to "(.*)", it will persist as a valid integer$')
|
||||
def set_the_max_attempts(step, max_attempts_set):
|
||||
# on firefox with selenium, the behaviour is different. eg 2.34 displays as 2.34 and is persisted as 2
|
||||
index = world.get_setting_entry_index(MAXIMUM_ATTEMPTS)
|
||||
world.css_fill('.wrapper-comp-setting .setting-input', max_attempts_set, index=index)
|
||||
if world.is_firefox():
|
||||
world.trigger_event('.wrapper-comp-setting .setting-input', index=index)
|
||||
world.save_component_and_reopen(step)
|
||||
world.verify_setting_entry(world.get_setting_entry(MAXIMUM_ATTEMPTS), MAXIMUM_ATTEMPTS, max_attempts_persisted, True)
|
||||
value = int(world.css_value('input.setting-input', index=index))
|
||||
assert value >= 0
|
||||
|
||||
|
||||
@step('Edit High Level Source is not visible')
|
||||
@@ -213,7 +223,11 @@ def verify_unset_display_name():
|
||||
|
||||
|
||||
def set_weight(weight):
|
||||
world.get_setting_entry(PROBLEM_WEIGHT).find_by_css('.setting-input')[0].fill(weight)
|
||||
index = world.get_setting_entry_index(PROBLEM_WEIGHT)
|
||||
world.css_fill('.wrapper-comp-setting .setting-input', weight, index=index)
|
||||
if world.is_firefox():
|
||||
world.trigger_event('.wrapper-comp-setting .setting-input', index=index, event='blur')
|
||||
world.trigger_event('a.save-button', event='focus')
|
||||
|
||||
|
||||
def open_high_level_source():
|
||||
|
||||
@@ -3,7 +3,6 @@ Feature: Create Section
|
||||
As a course author
|
||||
I want to create and edit sections
|
||||
|
||||
@skip
|
||||
Scenario: Add a new section to a course
|
||||
Given I have opened a new course in Studio
|
||||
When I click the New Section link
|
||||
|
||||
@@ -8,7 +8,7 @@ from selenium.webdriver.common.keys import Keys
|
||||
@step(u'I go to the static pages page')
|
||||
def go_to_static(_step):
|
||||
menu_css = 'li.nav-course-courseware'
|
||||
static_css = 'li.nav-course-courseware-pages'
|
||||
static_css = 'li.nav-course-courseware-pages a'
|
||||
world.css_click(menu_css)
|
||||
world.css_click(static_css)
|
||||
|
||||
@@ -38,14 +38,12 @@ def click_edit_delete(_step, edit_delete, page):
|
||||
|
||||
@step(u'I change the name to "([^"]*)"$')
|
||||
def change_name(_step, new_name):
|
||||
settings_css = '#settings-mode'
|
||||
settings_css = '#settings-mode a'
|
||||
world.css_click(settings_css)
|
||||
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)
|
||||
world.css_fill(input_css, new_name)
|
||||
if world.is_firefox():
|
||||
world.trigger_event(input_css)
|
||||
save_button = 'a.save-button'
|
||||
world.css_click(save_button)
|
||||
|
||||
|
||||
@@ -11,8 +11,8 @@ TEST_ROOT = settings.COMMON_TEST_DATA_ROOT
|
||||
@step(u'I go to the textbooks page')
|
||||
def go_to_uploads(_step):
|
||||
world.click_course_content()
|
||||
menu_css = 'li.nav-course-courseware-textbooks'
|
||||
world.css_find(menu_css).click()
|
||||
menu_css = 'li.nav-course-courseware-textbooks a'
|
||||
world.css_click(menu_css)
|
||||
|
||||
|
||||
@step(u'I should see a message telling me to create a new textbook')
|
||||
@@ -45,6 +45,8 @@ def click_new_textbook(_step, on):
|
||||
def name_textbook(_step, name):
|
||||
input_css = ".textbook input[name=textbook-name]"
|
||||
world.css_fill(input_css, name)
|
||||
if world.is_firefox():
|
||||
world.trigger_event(input_css)
|
||||
|
||||
|
||||
@step(u'I name the (first|second|third) chapter "([^"]*)"')
|
||||
@@ -52,6 +54,8 @@ def name_chapter(_step, ordinal, name):
|
||||
index = ["first", "second", "third"].index(ordinal)
|
||||
input_css = ".textbook .chapter{i} input.chapter-name".format(i=index+1)
|
||||
world.css_fill(input_css, name)
|
||||
if world.is_firefox():
|
||||
world.trigger_event(input_css)
|
||||
|
||||
|
||||
@step(u'I type in "([^"]*)" for the (first|second|third) chapter asset')
|
||||
@@ -59,6 +63,8 @@ def asset_chapter(_step, name, ordinal):
|
||||
index = ["first", "second", "third"].index(ordinal)
|
||||
input_css = ".textbook .chapter{i} input.chapter-asset-path".format(i=index+1)
|
||||
world.css_fill(input_css, name)
|
||||
if world.is_firefox():
|
||||
world.trigger_event(input_css)
|
||||
|
||||
|
||||
@step(u'I click the Upload Asset link for the (first|second|third) chapter')
|
||||
|
||||
@@ -13,7 +13,7 @@ TEST_ROOT = settings.COMMON_TEST_DATA_ROOT
|
||||
@step(u'I go to the files and uploads page')
|
||||
def go_to_uploads(_step):
|
||||
menu_css = 'li.nav-course-courseware'
|
||||
uploads_css = 'li.nav-course-courseware-uploads'
|
||||
uploads_css = 'li.nav-course-courseware-uploads a'
|
||||
world.css_click(menu_css)
|
||||
world.css_click(uploads_css)
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ Feature: Video Component
|
||||
And I have toggled captions
|
||||
Then when I view the video it does show the captions
|
||||
|
||||
# Video Alpha Features will work in Firefox only when Firefox is the active window
|
||||
Scenario: Autoplay is disabled in Studio for Video Alpha
|
||||
Given I have created a Video Alpha component
|
||||
Then when I view the videoalpha it does not have autoplay enabled
|
||||
|
||||
@@ -33,7 +33,9 @@ def hide_or_show_captions(step, shown):
|
||||
# click the button rather than the tooltip, so move the mouse
|
||||
# away to make it disappear.
|
||||
button = world.css_find(button_css)
|
||||
button.mouse_out()
|
||||
# mouse_out is not implemented on firefox with selenium
|
||||
if not world.is_firefox:
|
||||
button.mouse_out()
|
||||
world.css_click(button_css)
|
||||
|
||||
@step('I edit the component')
|
||||
|
||||
@@ -44,8 +44,8 @@ def is_css_not_present(css_selector, wait_time=5):
|
||||
|
||||
|
||||
@world.absorb
|
||||
def css_has_text(css_selector, text):
|
||||
return world.css_text(css_selector) == text
|
||||
def css_has_text(css_selector, text, index=0, max_attempts=5):
|
||||
return world.css_text(css_selector, index=index, max_attempts=max_attempts) == text
|
||||
|
||||
|
||||
@world.absorb
|
||||
@@ -235,6 +235,13 @@ def click_tools():
|
||||
def is_mac():
|
||||
return platform.mac_ver()[0] is not ''
|
||||
|
||||
@world.absorb
|
||||
def is_firefox():
|
||||
return world.browser.driver_name is 'Firefox'
|
||||
|
||||
@world.absorb
|
||||
def trigger_event(css_selector, event='change', index=0):
|
||||
world.browser.execute_script("$('{}:eq({})').trigger('{}')".format(css_selector, index, event))
|
||||
|
||||
@world.absorb
|
||||
def retry_on_exception(func, max_attempts=5):
|
||||
|
||||
@@ -8,4 +8,5 @@ def i_click_on_the_tab_and_check(step):
|
||||
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)
|
||||
|
||||
@@ -11,6 +11,7 @@ Feature: Login in as a registered user
|
||||
And I submit my credentials on the login form
|
||||
Then I should see the login error message "This account has not been activated"
|
||||
|
||||
# CHROME ONLY, firefox will not redirect properly
|
||||
Scenario: Login to an activated account
|
||||
Given I am an edX user
|
||||
And I am an activated user
|
||||
|
||||
@@ -226,7 +226,6 @@ def answer_problem(problem_type, correctness):
|
||||
|
||||
input_value = "8" if correctness == 'correct' else "5"
|
||||
choice = "choiceinput_0bc" if correctness == 'correct' else "choiceinput_1bc"
|
||||
world.css_check(inputfield(problem_type, choice=choice))
|
||||
world.css_fill(
|
||||
inputfield(
|
||||
problem_type,
|
||||
@@ -234,6 +233,7 @@ def answer_problem(problem_type, correctness):
|
||||
),
|
||||
input_value
|
||||
)
|
||||
world.css_check(inputfield(problem_type, choice=choice))
|
||||
|
||||
|
||||
def problem_has_answer(problem_type, answer_class):
|
||||
|
||||
@@ -3,6 +3,7 @@ Feature: Sign in
|
||||
As a new user
|
||||
I want to signup for a student account
|
||||
|
||||
# CHROME ONLY, firefox will not redirect properly
|
||||
Scenario: Sign up from the homepage
|
||||
Given I visit the homepage
|
||||
When I click the link with the text "Register Now"
|
||||
|
||||
@@ -81,7 +81,7 @@ nosexcover==1.0.7
|
||||
pep8==1.4.5
|
||||
pylint==0.28
|
||||
rednose==0.3
|
||||
selenium==2.33.0
|
||||
selenium==2.34.0
|
||||
splinter==0.5.4
|
||||
django_nose==1.1
|
||||
django-jasmine==0.3.2
|
||||
|
||||
Reference in New Issue
Block a user