Commit 193f315f by Muddasser

Converted all lettuce tests from cms/advanced_settings.feature to bokchoy

parent b1313671
@shard_1
Feature: CMS.Advanced (manual) course policy
In order to specify course policy settings for which no custom user interface exists
I want to be able to manually enter JSON key /value pairs
Scenario: A course author sees default advanced settings
Given I have opened a new course in Studio
When I select the Advanced Settings
Then I see default advanced settings
Scenario: Add new entries, and they appear alphabetically after save
Given I am on the Advanced Course Settings page in Studio
Then the settings are alphabetized
# Sauce labs does not play nicely with CodeMirror
@skip_sauce
Scenario: Test cancel editing key value
Given I am on the Advanced Course Settings page in Studio
When I edit the value of a policy key
And I press the "Cancel" notification button
Then the policy key value is unchanged
And I reload the page
Then the policy key value is unchanged
# Sauce labs does not play nicely with CodeMirror
@skip_sauce
Scenario: Test editing key value
Given I am on the Advanced Course Settings page in Studio
When I edit the value of a policy key and save
Then the policy key value is changed
And I reload the page
Then the policy key value is changed
# Sauce labs does not play nicely with CodeMirror
@skip_sauce
Scenario: Test how multi-line input appears
Given I am on the Advanced Course Settings page in Studio
When I create a JSON object as a value for "Discussion Topic Mapping"
Then it is displayed as formatted
And I reload the page
Then it is displayed as formatted
# Sauce labs does not play nicely with CodeMirror
@skip_sauce
Scenario: Test error if value supplied is of the wrong type
Given I am on the Advanced Course Settings page in Studio
When I create a JSON object as a value for "Course Display Name"
Then I get an error on save
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
# Sauce labs does not play nicely with CodeMirror
@skip_sauce
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
Then it is displayed as a string
And I reload the page
Then it is displayed as a string
# Sauce labs does not play nicely with CodeMirror
@skip_sauce
Scenario: Confirmation is shown on save
Given I am on the Advanced Course Settings page in Studio
When I edit the value of a policy key
And I press the "Save" notification button
Then I see a confirmation that my changes have been saved
Scenario: Deprecated Settings are not shown by default
Given I am on the Advanced Course Settings page in Studio
Then deprecated settings are not shown
Scenario: Deprecated Settings can be toggled
Given I am on the Advanced Course Settings page in Studio
When I toggle the display of deprecated settings
Then deprecated settings are then shown
And I toggle the display of deprecated settings
Then deprecated settings are not shown
# pylint: disable=missing-docstring
# pylint: disable=redefined-outer-name
from lettuce import world, step
from nose.tools import assert_false, assert_equal, assert_regexp_matches
from common import type_in_codemirror, press_the_notification_button, get_codemirror_value
KEY_CSS = '.key h3.title'
DISPLAY_NAME_KEY = "Course Display Name"
DISPLAY_NAME_VALUE = '"Robot Super Course"'
ADVANCED_MODULES_KEY = "Advanced Module List"
# A few deprecated settings for testing toggling functionality.
DEPRECATED_SETTINGS = ["CSS Class for Course Reruns", "Hide Progress Tab", "XQA Key"]
@step('I select the Advanced Settings$')
def i_select_advanced_settings(step):
world.click_course_settings()
# The click handlers are set up so that if you click <body>
# the menu disappears. This means that if we're even a *little*
# bit off on the last item ('Advanced Settings'), the menu
# will close and the test will fail.
# For this reason, we retrieve the link and visit it directly
# This is what the browser *should* be doing, since it's just a native
# link with no JavaScript involved.
link_css = 'li.nav-course-settings-advanced a'
world.wait_for_visible(link_css)
link = world.css_find(link_css).first['href']
world.visit(link)
@step('I am on the Advanced Course Settings page in Studio$')
def i_am_on_advanced_course_settings(step):
step.given('I have opened a new course in Studio')
step.given('I select the Advanced Settings')
@step(u'I edit the value of a policy key$')
def edit_the_value_of_a_policy_key(step):
type_in_codemirror(get_index_of(DISPLAY_NAME_KEY), 'X')
@step(u'I edit the value of a policy key and save$')
def edit_the_value_of_a_policy_key_and_save(step):
change_display_name_value(step, '"foo"')
@step('I create a JSON object as a value for "(.*)"$')
def create_JSON_object(step, key):
change_value(step, key, '{"key": "value", "key_2": "value_2"}')
@step('I create a non-JSON value not in quotes$')
def create_value_not_in_quotes(step):
change_display_name_value(step, 'quote me')
@step('I see default advanced settings$')
def i_see_default_advanced_settings(step):
# Test only a few of the existing properties (there are around 34 of them)
assert_policy_entries(
[ADVANCED_MODULES_KEY, DISPLAY_NAME_KEY, "Show Calculator"], ["[]", DISPLAY_NAME_VALUE, "false"])
@step('the settings are alphabetized$')
def they_are_alphabetized(step):
key_elements = world.css_find(KEY_CSS)
all_keys = []
for key in key_elements:
all_keys.append(key.value)
assert_equal(sorted(all_keys), all_keys, "policy keys were not sorted")
@step('it is displayed as formatted$')
def it_is_formatted(step):
assert_policy_entries(['Discussion Topic Mapping'], ['{\n "key": "value",\n "key_2": "value_2"\n}'])
@step('I get an error on save$')
def error_on_save(step):
assert_regexp_matches(
world.css_text('.error-item-message'),
"Value stored in a .* must be .*, found .*"
)
@step('it is displayed as a string')
def it_is_displayed_as_string(step):
assert_policy_entries([DISPLAY_NAME_KEY], ['"quote me"'])
@step(u'the policy key value is unchanged$')
def the_policy_key_value_is_unchanged(step):
assert_equal(get_display_name_value(), DISPLAY_NAME_VALUE)
@step(u'the policy key value is changed$')
def the_policy_key_value_is_changed(step):
assert_equal(get_display_name_value(), '"foo"')
@step(u'deprecated settings are (then|not) shown$')
def verify_deprecated_settings_shown(_step, expected):
for setting in DEPRECATED_SETTINGS:
if expected == "not":
assert_equal(-1, get_index_of(setting))
else:
world.wait_for(lambda _: get_index_of(setting) != -1)
@step(u'I toggle the display of deprecated settings$')
def toggle_deprecated_settings(_step):
world.css_click(".deprecated-settings-label")
def assert_policy_entries(expected_keys, expected_values):
for key, value in zip(expected_keys, expected_values):
index = get_index_of(key)
assert_false(index == -1, "Could not find key: {key}".format(key=key))
found_value = get_codemirror_value(index)
assert_equal(
value, found_value,
"Expected {} to have value {} but found {}".format(key, value, found_value)
)
def get_index_of(expected_key):
for i, element in enumerate(world.css_find(KEY_CSS)):
# Sometimes get stale reference if I hold on to the array of elements
key = world.css_value(KEY_CSS, index=i)
if key == expected_key:
return i
return -1
def get_display_name_value():
index = get_index_of(DISPLAY_NAME_KEY)
return get_codemirror_value(index)
def change_display_name_value(step, new_value):
change_value(step, DISPLAY_NAME_KEY, new_value)
def change_value(step, key, new_value):
index = get_index_of(key)
type_in_codemirror(index, new_value)
press_the_notification_button(step, "Save")
world.wait_for_ajax_complete()
......@@ -4,10 +4,10 @@
import json
from lettuce import world, step
from nose.tools import assert_equal, assert_true
from common import type_in_codemirror, open_new_course
from advanced_settings import change_value, ADVANCED_MODULES_KEY
from common import type_in_codemirror, open_new_course, press_the_notification_button
from course_import import import_file
KEY_CSS = '.key h3.title'
DISPLAY_NAME = "Display Name"
MAXIMUM_ATTEMPTS = "Maximum Attempts"
PROBLEM_WEIGHT = "Problem Weight"
......@@ -16,6 +16,7 @@ SHOW_ANSWER = "Show Answer"
SHOW_RESET_BUTTON = "Show Reset Button"
TIMER_BETWEEN_ATTEMPTS = "Timer Between Attempts"
MATLAB_API_KEY = "Matlab API key"
ADVANCED_MODULES_KEY = "Advanced Module List"
@step('I have created a Blank Common Problem$')
......@@ -380,6 +381,23 @@ def set_weight(weight):
world.set_field_value(index, weight)
def get_index_of(expected_key):
for i, element in enumerate(world.css_find(KEY_CSS)):
# Sometimes get stale reference if I hold on to the array of elements
key = world.css_value(KEY_CSS, index=i)
if key == expected_key:
return i
return -1
def change_value(step, key, new_value):
index = get_index_of(key)
type_in_codemirror(index, new_value)
press_the_notification_button(step, "Save")
world.wait_for_ajax_complete()
def open_high_level_source():
world.edit_component()
world.css_click('.launch-latex-compiler > a')
......@@ -107,6 +107,12 @@ class AdvancedSettingsPage(CoursePage):
return -1
def get_index_of(self, key):
"""
Returns the index of a setting passed as key.
"""
return self._get_index_of(key)
def save(self):
press_the_notification_button(self, "Save")
......@@ -118,6 +124,19 @@ class AdvancedSettingsPage(CoursePage):
type_in_codemirror(self, index, new_value)
self.save()
def set_value_without_saving(self, key, new_value):
"""
Set value without saving it.
"""
index = self._get_index_of(key)
type_in_codemirror(self, index, new_value)
def click_toggle_button(self):
"""
Click toggle button with css class deprecated-settings-label.
"""
self.q(css='.deprecated-settings-label').click()
def get(self, key):
index = self._get_index_of(key)
return get_codemirror_value(self, index)
......@@ -222,3 +241,10 @@ class AdvancedSettingsPage(CoursePage):
'learning_info',
'instructor_info'
]
def get_all_displayed_settings(self):
"""
Get names of all displayed settings.
"""
query = self.q(css=SETTINGS_NAME_SELECTOR)
return query.text
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment