advanced settings bokchoy tests III
This commit is contained in:
@@ -1,39 +0,0 @@
|
||||
@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
|
||||
|
||||
# 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
|
||||
|
||||
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
|
||||
@@ -2,122 +2,10 @@
|
||||
# pylint: disable=redefined-outer-name
|
||||
|
||||
from lettuce import step, world
|
||||
from nose.tools import assert_equal, assert_false, assert_regexp_matches
|
||||
|
||||
from common import get_codemirror_value, press_the_notification_button, type_in_codemirror
|
||||
from cms.djangoapps.contentstore.features.common import press_the_notification_button, type_in_codemirror
|
||||
|
||||
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.wait_for_js_to_load() # pylint: disable=no-member
|
||||
world.wait_for_js_variable_truthy('window.studioNavMenuActive') # pylint: disable=no-member
|
||||
|
||||
for _ in range(5):
|
||||
world.click_course_settings() # pylint: disable=no-member
|
||||
|
||||
# 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'
|
||||
try:
|
||||
world.wait_for_visible(link_css) # pylint: disable=no-member
|
||||
break
|
||||
except AssertionError:
|
||||
continue
|
||||
|
||||
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('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):
|
||||
@@ -130,15 +18,6 @@ def get_index_of(expected_key):
|
||||
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)
|
||||
|
||||
@@ -51,12 +51,23 @@ class AdvancedSettingsPage(CoursePage):
|
||||
"""
|
||||
return self.q(css=DEPRECATED_SETTINGS_BUTTON_SELECTOR).text[0]
|
||||
|
||||
def check_deprecated_settings_visibility(self):
|
||||
def is_deprecated_setting_visible(self):
|
||||
"""
|
||||
Returns true if deprecated settings are visible
|
||||
"""
|
||||
return self.q(css=DEPRECATED_SETTINGS_SELECTOR).visible
|
||||
|
||||
def toggle_deprecated_settings(self):
|
||||
"""
|
||||
Show deprecated Settings
|
||||
"""
|
||||
button_text = self.deprecated_settings_button_text
|
||||
self.q(css=DEPRECATED_SETTINGS_BUTTON_SELECTOR).click()
|
||||
if button_text == 'Show Deprecated Settings':
|
||||
self.wait_for_element_presence(DEPRECATED_SETTINGS_SELECTOR, 'Deprecated Settings are present')
|
||||
else:
|
||||
self.wait_for_element_absence(DEPRECATED_SETTINGS_SELECTOR, 'Deprecated Settings are not present')
|
||||
|
||||
def wait_for_modal_load(self):
|
||||
"""
|
||||
Wait for validation response from the server, and make sure that
|
||||
@@ -134,6 +145,9 @@ class AdvancedSettingsPage(CoursePage):
|
||||
return self.q(css=ERROR_ITEM_CONTENT_SELECTOR).text
|
||||
|
||||
def _get_index_of(self, expected_key):
|
||||
"""
|
||||
Returns the index of expected key
|
||||
"""
|
||||
for i, element in enumerate(self.q(css=KEY_CSS)):
|
||||
# Sometimes get stale reference if I hold on to the array of elements
|
||||
key = self.q(css=KEY_CSS).nth(i).text[0]
|
||||
|
||||
@@ -7,13 +7,14 @@ from __future__ import unicode_literals
|
||||
import os
|
||||
import random
|
||||
import string
|
||||
import json
|
||||
from textwrap import dedent
|
||||
|
||||
from bok_choy.promise import EmptyPromise
|
||||
from mock import patch
|
||||
from nose.plugins.attrib import attr
|
||||
|
||||
from base_studio_test import StudioCourseTest
|
||||
from common.test.acceptance.tests.studio.base_studio_test import StudioCourseTest
|
||||
from common.test.acceptance.fixtures.course import XBlockFixtureDesc
|
||||
from common.test.acceptance.pages.common.utils import add_enrollment_course_modes
|
||||
from common.test.acceptance.pages.lms.courseware import CoursewarePage
|
||||
@@ -435,7 +436,93 @@ class AdvancedSettingsValidationTest(StudioCourseTest):
|
||||
"""
|
||||
button_text = self.advanced_settings.deprecated_settings_button_text
|
||||
self.assertEqual(button_text, 'Show Deprecated Settings')
|
||||
self.assertFalse(self.advanced_settings.check_deprecated_settings_visibility())
|
||||
self.assertFalse(self.advanced_settings.is_deprecated_setting_visible())
|
||||
|
||||
def test_deprecated_settings_can_be_toggled(self):
|
||||
"""
|
||||
Scenario: Test that advanced settings can toggle deprecated settings
|
||||
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
|
||||
"""
|
||||
|
||||
self.advanced_settings.toggle_deprecated_settings()
|
||||
button_text = self.advanced_settings.deprecated_settings_button_text
|
||||
self.assertEqual(
|
||||
button_text,
|
||||
'Hide Deprecated Settings',
|
||||
"Button text should change to 'Hide Deprecated Settings' after the click"
|
||||
)
|
||||
self.assertTrue(self.advanced_settings.is_deprecated_setting_visible())
|
||||
self.advanced_settings.toggle_deprecated_settings()
|
||||
self.assertFalse(self.advanced_settings.is_deprecated_setting_visible())
|
||||
self.assertEqual(
|
||||
self.advanced_settings.deprecated_settings_button_text,
|
||||
'Show Deprecated Settings',
|
||||
"Button text should change to 'Show Deprecated Settings' after the click"
|
||||
)
|
||||
|
||||
def test_multi_line_input(self):
|
||||
"""
|
||||
Scenario: Test that advanced settings correctly shows the multi-line input
|
||||
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
|
||||
"""
|
||||
|
||||
inputs = {
|
||||
"key": "value",
|
||||
"key_2": "value_2"
|
||||
}
|
||||
json_input = json.dumps(inputs)
|
||||
self.advanced_settings.set('Discussion Topic Mapping', json_input)
|
||||
self.assertEqual(
|
||||
self.advanced_settings.get('Discussion Topic Mapping'),
|
||||
'{\n "key": "value",\n "key_2": "value_2"\n}'
|
||||
)
|
||||
|
||||
def test_automatic_quoting_of_non_json_value(self):
|
||||
"""
|
||||
Scenario: Test that advanced settings automatically quotes the field input
|
||||
upon saving
|
||||
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
|
||||
"""
|
||||
|
||||
self.advanced_settings.set(self.course_name_key, self.course_name_value)
|
||||
self.assertEqual(
|
||||
self.advanced_settings.get(self.course_name_key),
|
||||
'"Test Name"'
|
||||
)
|
||||
|
||||
def test_validation_error_for_wrong_input_type(self):
|
||||
"""
|
||||
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
|
||||
"""
|
||||
|
||||
course_display_name = self.advanced_settings.get('Course Display Name')
|
||||
inputs = {
|
||||
"key": "value",
|
||||
"key_2": "value_2"
|
||||
}
|
||||
json_input = json.dumps(inputs)
|
||||
self.advanced_settings.set('Course Display Name', json_input)
|
||||
self.advanced_settings.wait_for_modal_load()
|
||||
self.check_modal_shows_correct_contents(['Course Display Name'])
|
||||
self.advanced_settings.refresh_and_wait_for_load()
|
||||
self.assertEquals(
|
||||
self.advanced_settings.get('Course Display Name'),
|
||||
course_display_name,
|
||||
'Wrong input for Course Display Name must not change its value'
|
||||
)
|
||||
|
||||
def test_modal_shows_one_validation_error(self):
|
||||
"""
|
||||
|
||||
Reference in New Issue
Block a user