From 62a8c420edefab43a67429949394f31c4a6c327e Mon Sep 17 00:00:00 2001 From: Julian Arni Date: Wed, 25 Sep 2013 15:37:40 -0400 Subject: [PATCH 1/8] Check for exceptions when rendering studio and students views. Otherwise it's possible to reach stuck states. --- cms/djangoapps/contentstore/views/preview.py | 19 +++++++++++++++--- cms/templates/html_error.html | 21 ++++++++++++++++++++ 2 files changed, 37 insertions(+), 3 deletions(-) create mode 100644 cms/templates/html_error.html diff --git a/cms/djangoapps/contentstore/views/preview.py b/cms/djangoapps/contentstore/views/preview.py index eb2d92880d..22a0af8171 100644 --- a/cms/djangoapps/contentstore/views/preview.py +++ b/cms/djangoapps/contentstore/views/preview.py @@ -6,7 +6,7 @@ from django.conf import settings from django.http import HttpResponse, Http404, HttpResponseBadRequest, HttpResponseForbidden from django.core.urlresolvers import reverse from django.contrib.auth.decorators import login_required -from mitxmako.shortcuts import render_to_response +from mitxmako.shortcuts import render_to_response, render_to_string from xmodule_modifiers import replace_static_urls, wrap_xmodule from xmodule.error_module import ErrorDescriptor @@ -79,9 +79,18 @@ def preview_component(request, location): # can bind to it correctly component.runtime.wrappers.append(partial(wrap_xmodule, 'xmodule_edit.html')) + + try: + content = component.render('studio_view').content + # catch exceptions indiscriminately, since after this point they escape the + # dungeon and surface as uneditable, unsaveable, and undeletable + # component-goblins. + except Exception as exc: #pylint: disable=W0703 + content = render_to_string('html_error.html', {'message': str(exc)}) + return render_to_response('component.html', { 'preview': get_preview_html(request, component, 0), - 'editor': component.render('studio_view').content, + 'editor': content }) @@ -157,4 +166,8 @@ def get_preview_html(request, descriptor, idx): specified by the descriptor and idx. """ module = load_preview_module(request, str(idx), descriptor) - return module.render("student_view").content + try: + content = module.render("student_view").content + except Exception as exc: #pylint: disable=W0703 + content = render_to_string('html_error.html', {'message': str(exc)}) + return content diff --git a/cms/templates/html_error.html b/cms/templates/html_error.html new file mode 100644 index 0000000000..7bc75ad0a9 --- /dev/null +++ b/cms/templates/html_error.html @@ -0,0 +1,21 @@ +<%! from django.utils.translation import ugettext as _ %> +<%! from django.core.urlresolvers import reverse %> +<%block name="bodyclass">error + +<%block name="content"> +
+

+ ${_("We're having trouble rendering your component.")} +

+ % if message: +

+ ${_("Error message:")} +

+ +
+      ${message | h}
+      
+
+ % endif +
+ From faadc33fccdaea9e4e9eda9d3e91c470f1115342 Mon Sep 17 00:00:00 2001 From: Frances Botsford Date: Thu, 26 Sep 2013 12:12:15 -0400 Subject: [PATCH 2/8] leveraging some of the existing notification styling for component errors in studio --- cms/templates/html_error.html | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/cms/templates/html_error.html b/cms/templates/html_error.html index 7bc75ad0a9..f0f82d959b 100644 --- a/cms/templates/html_error.html +++ b/cms/templates/html_error.html @@ -3,19 +3,25 @@ <%block name="bodyclass">error <%block name="content"> -
-

- ${_("We're having trouble rendering your component.")} -

- % if message: -

- ${_("Error message:")} -

- -
-      ${message | h}
-      
-
- % endif +
+
+ +
+

+ + ${_("We're having trouble rendering your component")} +

+ +

You can try re-editing your component to check that your syntax is correct.

+ + % if message: +

+ ${_("Error message:")} + ${message | h} +

+ % endif + + +
From 2721966d767783c6c541467932adc70714896f4b Mon Sep 17 00:00:00 2001 From: Julian Arni Date: Thu, 26 Sep 2013 16:27:06 -0400 Subject: [PATCH 3/8] Added acceptance tests for get_html exception handling Make tests conform to new import UI --- .../component_settings_editor_helpers.py | 8 -- .../contentstore/features/import.py | 22 ++++++ .../features/problem-editor.feature | 12 ++- .../contentstore/features/problem-editor.py | 69 +++++++++++++++--- .../contentstore/views/import_export.py | 5 +- .../about/overview.html | 47 ++++++++++++ .../chapter/Week_1.xml | 3 + .../data/get_html_exception_test/course.xml | 1 + .../get_html_exception_test/course/hakj.xml | 3 + .../get_html_exception_test/custom_tags/book | 1 + .../custom_tags/discuss | 1 + .../custom_tags/handout | 1 + .../get_html_exception_test/custom_tags/image | 1 + .../get_html_exception_test/custom_tags/link | 1 + .../custom_tags/slides | 1 + .../policies/assets.json | 1 + .../policies/hakj/grading_policy.json | 1 + .../policies/hakj/policy.json | 1 + .../8af0ab4186c04c2eb08a92926e36d1ce.xml | 3 + .../vertical/vertical_74cca8afc761.xml | 3 + .../imports/get_html_exception_test.tar.gz | Bin 0 -> 24064 bytes 21 files changed, 166 insertions(+), 19 deletions(-) create mode 100644 cms/djangoapps/contentstore/features/import.py create mode 100644 common/test/data/get_html_exception_test/about/overview.html create mode 100644 common/test/data/get_html_exception_test/chapter/Week_1.xml create mode 100644 common/test/data/get_html_exception_test/course.xml create mode 100644 common/test/data/get_html_exception_test/course/hakj.xml create mode 100644 common/test/data/get_html_exception_test/custom_tags/book create mode 100644 common/test/data/get_html_exception_test/custom_tags/discuss create mode 100644 common/test/data/get_html_exception_test/custom_tags/handout create mode 100644 common/test/data/get_html_exception_test/custom_tags/image create mode 100644 common/test/data/get_html_exception_test/custom_tags/link create mode 100644 common/test/data/get_html_exception_test/custom_tags/slides create mode 100644 common/test/data/get_html_exception_test/policies/assets.json create mode 100644 common/test/data/get_html_exception_test/policies/hakj/grading_policy.json create mode 100644 common/test/data/get_html_exception_test/policies/hakj/policy.json create mode 100644 common/test/data/get_html_exception_test/sequential/8af0ab4186c04c2eb08a92926e36d1ce.xml create mode 100644 common/test/data/get_html_exception_test/vertical/vertical_74cca8afc761.xml create mode 100644 common/test/data/imports/get_html_exception_test.tar.gz diff --git a/cms/djangoapps/contentstore/features/component_settings_editor_helpers.py b/cms/djangoapps/contentstore/features/component_settings_editor_helpers.py index 9881290eba..45fc568f23 100644 --- a/cms/djangoapps/contentstore/features/component_settings_editor_helpers.py +++ b/cms/djangoapps/contentstore/features/component_settings_editor_helpers.py @@ -39,7 +39,6 @@ def click_new_component_button(step, component_button_css): ) world.css_click(component_button_css) - @world.absorb def click_component_from_menu(category, boilerplate, expected_css): """ @@ -64,13 +63,11 @@ def edit_component_and_select_settings(): world.css_click('a.edit-button') world.css_click('#settings-mode a') - @world.absorb def edit_component(): world.wait_for(lambda _driver: world.css_visible('a.edit-button')) world.css_click('a.edit-button') - @world.absorb def verify_setting_entry(setting, display_name, value, explicitly_set): """ @@ -100,7 +97,6 @@ def verify_setting_entry(setting, display_name, value, explicitly_set): assert_equal(explicitly_set, settingClearButton.has_class('active')) assert_equal(not explicitly_set, settingClearButton.has_class('inactive')) - @world.absorb def verify_all_setting_entries(expected_entries): settings = world.browser.find_by_css('.wrapper-comp-setting') @@ -111,7 +107,6 @@ def verify_all_setting_entries(expected_entries): expected_entries[counter][1], expected_entries[counter][2] ) - @world.absorb def save_component_and_reopen(step): world.css_click("a.save-button") @@ -121,7 +116,6 @@ def save_component_and_reopen(step): reload_the_page(step) edit_component_and_select_settings() - @world.absorb def cancel_component(step): world.css_click("a.cancel-button") @@ -129,12 +123,10 @@ def cancel_component(step): # they are not persisted. Refresh the browser to make sure the changes were not persisted. reload_the_page(step) - @world.absorb def revert_setting_entry(label): get_setting_entry(label).find_by_css('.setting-clear')[0].click() - @world.absorb def get_setting_entry(label): def get_setting(): diff --git a/cms/djangoapps/contentstore/features/import.py b/cms/djangoapps/contentstore/features/import.py new file mode 100644 index 0000000000..1efb40e974 --- /dev/null +++ b/cms/djangoapps/contentstore/features/import.py @@ -0,0 +1,22 @@ +import os +from lettuce import world +from django.conf import settings + +@world.absorb +def import_file(filename): + world.browser.execute_script("$('input.file-input').css('display', 'block')") + path = os.path.join(settings.COMMON_TEST_DATA_ROOT, "imports", filename) + world.browser.attach_file('course-data', os.path.abspath(path)) + world.css_click('input.submit-button') + # Go to course outline + menu_css = 'li.nav-course-courseware' + outline_css = 'li.nav-course-courseware-outline a' + world.css_click(menu_css) + world.css_click(outline_css) + +@world.absorb +def go_to_import(): + menu_css = 'li.nav-course-tools' + import_css = 'li.nav-course-tools-import a' + world.css_click(menu_css) + world.css_click(import_css) diff --git a/cms/djangoapps/contentstore/features/problem-editor.feature b/cms/djangoapps/contentstore/features/problem-editor.feature index e3f659a929..e73bdee81b 100644 --- a/cms/djangoapps/contentstore/features/problem-editor.feature +++ b/cms/djangoapps/contentstore/features/problem-editor.feature @@ -3,7 +3,7 @@ Feature: CMS.Problem Editor As a course author, I want to be able to create problems and edit their settings. Scenario: User can view metadata - Given I have created a Blank Common Problem + Given I have an empty course When I edit and select Settings Then I see the advanced settings and their expected values And Edit High Level Source is not visible @@ -89,3 +89,13 @@ Feature: CMS.Problem Editor When I edit and compile the High Level Source Then my change to the High Level Source is persisted And when I view the High Level Source I see my changes + + Scenario: Exceptions don't cause problem to be uneditable (bug STUD-786) + Given I have created a Blank Common Problem + And I go to the import page + And I import the file "get_html_exception_test.tar.gz" + When I go to the unit "Probability and BMI" + And I click on the link "edit a draft" + Then I see a message that says "We're having trouble rendering your component" + And I can edit the problem + diff --git a/cms/djangoapps/contentstore/features/problem-editor.py b/cms/djangoapps/contentstore/features/problem-editor.py index fca2249066..ba212b513a 100644 --- a/cms/djangoapps/contentstore/features/problem-editor.py +++ b/cms/djangoapps/contentstore/features/problem-editor.py @@ -1,9 +1,15 @@ # disable missing docstring #pylint: disable=C0111 +import os +import json from lettuce import world, step from nose.tools import assert_equal, assert_true # pylint: disable=E0611 from common import type_in_codemirror +from time import sleep + + +from pdb import set_trace DISPLAY_NAME = "Display Name" MAXIMUM_ATTEMPTS = "Maximum Attempts" @@ -24,7 +30,7 @@ def i_created_blank_common_problem(step): @step('I edit and select Settings$') -def i_edit_and_select_settings(step): +def i_edit_and_select_settings(_step): world.edit_component_and_select_settings() @@ -41,7 +47,7 @@ def i_see_advanced_settings_with_values(step): @step('I can modify the display name') -def i_can_modify_the_display_name(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). index = world.get_setting_entry_index(DISPLAY_NAME) @@ -58,7 +64,7 @@ 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): +def i_can_modify_the_display_name_with_special_chars(_step): index = world.get_setting_entry_index(DISPLAY_NAME) world.css_fill('.wrapper-comp-setting .setting-input', "updated ' \" &", index=index) if world.is_firefox(): @@ -73,7 +79,7 @@ def special_chars_persisted_on_save(step): @step('I can revert the display name to unset') -def can_revert_display_name_to_unset(step): +def can_revert_display_name_to_unset(_step): world.revert_setting_entry(DISPLAY_NAME) verify_unset_display_name() @@ -85,7 +91,7 @@ def my_display_name_is_persisted_on_save(step): @step('I can select Per Student for Randomization') -def i_can_select_per_student_for_randomization(step): +def i_can_select_per_student_for_randomization(_step): world.browser.select(RANDOMIZATION, "Per Student") verify_modified_randomization() @@ -104,7 +110,7 @@ def i_can_revert_to_default_for_randomization(step): @step('I can set the weight to "(.*)"?') -def i_can_set_weight(step, weight): +def i_can_set_weight(_step, weight): set_weight(weight) verify_modified_weight() @@ -175,14 +181,14 @@ def create_latex_problem(step): @step('I edit and compile the High Level Source') -def edit_latex_source(step): +def edit_latex_source(_step): open_high_level_source() type_in_codemirror(1, "hi") world.css_click('.hls-compile') @step('my change to the High Level Source is persisted') -def high_level_source_persisted(step): +def high_level_source_persisted(_step): def verify_text(driver): css_sel = '.problem div>span' return world.css_text(css_sel) == 'hi' @@ -191,10 +197,55 @@ def high_level_source_persisted(step): @step('I view the High Level Source I see my changes') -def high_level_source_in_editor(step): +def high_level_source_in_editor(_step): open_high_level_source() assert_equal('hi', world.css_value('.source-edit-box')) +@step(u'I have an empty course') +def i_have_empty_course(step): + step.given('I have clicked the new unit button') + +@step(u'I go to the import page') +def i_go_to_import(_step): + world.go_to_import() + + +@step(u'I import the file "([^"]*)"$') +def i_import_the_file(_step, filename): + world.import_file(filename) + + +@step(u'I click on the link "([^"]*)"$') +def i_click_on(_step, link): + #go = "$(\"a:contains('{0}')\").click()".format(link) + world.browser.click_link_by_text(link) + + +@step(u'I go to the vertical "([^"]*)"$') +def i_go_to_vertical(_step, vertical): + world.css_click("span:contains('{0}')".format(vertical)) + + +@step(u'I go to the unit "([^"]*)"$') +def i_go_to_unit(_step, unit): + loc = "window.location = $(\"span:contains('{0}')\").closest('a').attr('href')".format(unit) + world.browser.execute_script(loc) + + +@step(u'I see a message that says "([^"]*)"$') +def i_can_see_message(_step, msg): + msg = json.dumps(msg) # escape quotes + world.browser.is_text_present(msg) + + +@step(u'I can edit the problem$') +def i_can_edit_problem(_step): + try: + world.edit_component() + except TimeoutException: + assert_true(False) + assert_true(True) + def verify_high_level_source_links(step, visible): if visible: diff --git a/cms/djangoapps/contentstore/views/import_export.py b/cms/djangoapps/contentstore/views/import_export.py index 67e64d67d0..aa4fa6b606 100644 --- a/cms/djangoapps/contentstore/views/import_export.py +++ b/cms/djangoapps/contentstore/views/import_export.py @@ -35,6 +35,8 @@ from .access import get_location_and_verify_access from util.json_request import JsonResponse from extract_tar import safetar_extractall +import traceback + __all__ = ['import_course', 'import_status', 'generate_export_course', 'export_course'] @@ -193,6 +195,7 @@ def import_course(request, org, course, name): if not dirpath: return JsonResponse( { + 'ErrMsg': _('Could not find the course.xml file in the package.'), 'Stage': 2 }, @@ -227,7 +230,7 @@ def import_course(request, org, course, name): except Exception as exception: # pylint: disable=W0703 return JsonResponse( { - 'ErrMsg': str(exception), + 'ErrMsg': str(exception) + traceback.format_exc(), 'Stage': session_status[key] }, status=400 diff --git a/common/test/data/get_html_exception_test/about/overview.html b/common/test/data/get_html_exception_test/about/overview.html new file mode 100644 index 0000000000..961786b8f4 --- /dev/null +++ b/common/test/data/get_html_exception_test/about/overview.html @@ -0,0 +1,47 @@ +
+

About This Course

+

Include your long course description here. The long course description should contain 150-400 words.

+ +

This is paragraph 2 of the long course description. Add more paragraphs as needed. Make sure to enclose them in paragraph tags.

+
+ +
+

Prerequisites

+

Add information about course prerequisites here.

+
+ +
+

Course Staff

+
+
+ +
+ +

Staff Member #1

+

Biography of instructor/staff member #1

+
+ +
+
+ +
+ +

Staff Member #2

+

Biography of instructor/staff member #2

+
+
+ +
+
+

Frequently Asked Questions

+
+

Do I need to buy a textbook?

+

No, a free online version of Chemistry: Principles, Patterns, and Applications, First Edition by Bruce Averill and Patricia Eldredge will be available, though you can purchase a printed version (published by FlatWorld Knowledge) if you’d like.

+
+ +
+

Question #2

+

Your answer would be displayed here.

+
+
+
diff --git a/common/test/data/get_html_exception_test/chapter/Week_1.xml b/common/test/data/get_html_exception_test/chapter/Week_1.xml new file mode 100644 index 0000000000..c6e1295a69 --- /dev/null +++ b/common/test/data/get_html_exception_test/chapter/Week_1.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/get_html_exception_test/course.xml b/common/test/data/get_html_exception_test/course.xml new file mode 100644 index 0000000000..bedccb4153 --- /dev/null +++ b/common/test/data/get_html_exception_test/course.xml @@ -0,0 +1 @@ + diff --git a/common/test/data/get_html_exception_test/course/hakj.xml b/common/test/data/get_html_exception_test/course/hakj.xml new file mode 100644 index 0000000000..cd83c98bac --- /dev/null +++ b/common/test/data/get_html_exception_test/course/hakj.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/get_html_exception_test/custom_tags/book b/common/test/data/get_html_exception_test/custom_tags/book new file mode 100644 index 0000000000..8b13789179 --- /dev/null +++ b/common/test/data/get_html_exception_test/custom_tags/book @@ -0,0 +1 @@ + diff --git a/common/test/data/get_html_exception_test/custom_tags/discuss b/common/test/data/get_html_exception_test/custom_tags/discuss new file mode 100644 index 0000000000..ac56590074 --- /dev/null +++ b/common/test/data/get_html_exception_test/custom_tags/discuss @@ -0,0 +1 @@ + Discussion: ${tag} \ No newline at end of file diff --git a/common/test/data/get_html_exception_test/custom_tags/handout b/common/test/data/get_html_exception_test/custom_tags/handout new file mode 100644 index 0000000000..014e6f3305 --- /dev/null +++ b/common/test/data/get_html_exception_test/custom_tags/handout @@ -0,0 +1 @@ + ${text_of_link} diff --git a/common/test/data/get_html_exception_test/custom_tags/image b/common/test/data/get_html_exception_test/custom_tags/image new file mode 100644 index 0000000000..d2939ba88c --- /dev/null +++ b/common/test/data/get_html_exception_test/custom_tags/image @@ -0,0 +1 @@ + diff --git a/common/test/data/get_html_exception_test/custom_tags/link b/common/test/data/get_html_exception_test/custom_tags/link new file mode 100644 index 0000000000..e389844059 --- /dev/null +++ b/common/test/data/get_html_exception_test/custom_tags/link @@ -0,0 +1 @@ + ${text_of_link} diff --git a/common/test/data/get_html_exception_test/custom_tags/slides b/common/test/data/get_html_exception_test/custom_tags/slides new file mode 100644 index 0000000000..7a33ffd6c7 --- /dev/null +++ b/common/test/data/get_html_exception_test/custom_tags/slides @@ -0,0 +1 @@ +Lecture Slides Handout [Clean ][Annotated] \ No newline at end of file diff --git a/common/test/data/get_html_exception_test/policies/assets.json b/common/test/data/get_html_exception_test/policies/assets.json new file mode 100644 index 0000000000..9e26dfeeb6 --- /dev/null +++ b/common/test/data/get_html_exception_test/policies/assets.json @@ -0,0 +1 @@ +{} \ No newline at end of file diff --git a/common/test/data/get_html_exception_test/policies/hakj/grading_policy.json b/common/test/data/get_html_exception_test/policies/hakj/grading_policy.json new file mode 100644 index 0000000000..272cb4fec6 --- /dev/null +++ b/common/test/data/get_html_exception_test/policies/hakj/grading_policy.json @@ -0,0 +1 @@ +{"GRADER": [{"short_label": "HW", "min_count": 12, "type": "Homework", "drop_count": 2, "weight": 0.15}, {"min_count": 12, "type": "Lab", "drop_count": 2, "weight": 0.15}, {"short_label": "Midterm", "min_count": 1, "type": "Midterm Exam", "drop_count": 0, "weight": 0.3}, {"short_label": "Final", "min_count": 1, "type": "Final Exam", "drop_count": 0, "weight": 0.4}], "GRADE_CUTOFFS": {"Pass": 0.5}} \ No newline at end of file diff --git a/common/test/data/get_html_exception_test/policies/hakj/policy.json b/common/test/data/get_html_exception_test/policies/hakj/policy.json new file mode 100644 index 0000000000..defbd8245d --- /dev/null +++ b/common/test/data/get_html_exception_test/policies/hakj/policy.json @@ -0,0 +1 @@ +{"course/hakj": {"ispublic": false, "graded": false, "tabs": [{"type": "courseware"}, {"type": "course_info", "name": "Course Info"}, {"type": "textbooks"}, {"type": "discussion", "name": "Discussion"}, {"type": "wiki", "name": "Wiki"}, {"type": "progress", "name": "Progress"}], "remote_gradebook": {}, "giturl": null, "discussion_topics": {"General": {"id": "i4x-edx-ctt101-course-html_exception_test"}}, "due": null, "source_file": null, "html_textbooks": [], "announcement": null, "showanswer": "attempted", "display_name": "Principles of Biostatistics", "graceperiod": "900 seconds", "allow_anonymous": false, "tags": [], "enrollment_start": "2013-08-26T04:00:00Z", "start": "2013-08-26T04:00:00Z", "xml_attributes": {"filename": ["course/html_exception_test.xml", "course/html_exception_test.xml"]}, "pdf_textbooks": [], "days_early_for_beta": 100, "advanced_modules": [], "format": null, "xqa_key": "AlQ7TjCl7Rfhc0Am6WguqjeUzGz7AuVt", "enrollment_end": "2013-09-25T04:00:00Z", "end": "2013-12-20T05:00:00Z", "show_calculator": "Yes", "hide_from_toc": false, "rerandomize": "never", "cohort_config": {}}} \ No newline at end of file diff --git a/common/test/data/get_html_exception_test/sequential/8af0ab4186c04c2eb08a92926e36d1ce.xml b/common/test/data/get_html_exception_test/sequential/8af0ab4186c04c2eb08a92926e36d1ce.xml new file mode 100644 index 0000000000..5885a6ae5c --- /dev/null +++ b/common/test/data/get_html_exception_test/sequential/8af0ab4186c04c2eb08a92926e36d1ce.xml @@ -0,0 +1,3 @@ + + + diff --git a/common/test/data/get_html_exception_test/vertical/vertical_74cca8afc761.xml b/common/test/data/get_html_exception_test/vertical/vertical_74cca8afc761.xml new file mode 100644 index 0000000000..7a02d7565c --- /dev/null +++ b/common/test/data/get_html_exception_test/vertical/vertical_74cca8afc761.xml @@ -0,0 +1,3 @@ + + PDF of Problem Set 3 + diff --git a/common/test/data/imports/get_html_exception_test.tar.gz b/common/test/data/imports/get_html_exception_test.tar.gz new file mode 100644 index 0000000000000000000000000000000000000000..bcd0b8df8c9ad6f718595681332bd29c23e1ac42 GIT binary patch literal 24064 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 literal 0 HcmV?d00001 From 9f188ed20c36634e26f181927a9f5a883e24fa38 Mon Sep 17 00:00:00 2001 From: Frances Botsford Date: Tue, 8 Oct 2013 16:34:50 -0400 Subject: [PATCH 4/8] additional copy and styling for component syntax error in studio --- .../contentstore/features/problem-editor.py | 2 -- cms/static/sass/views/_unit.scss | 13 +++++++++++++ cms/templates/html_error.html | 5 ++--- 3 files changed, 15 insertions(+), 5 deletions(-) diff --git a/cms/djangoapps/contentstore/features/problem-editor.py b/cms/djangoapps/contentstore/features/problem-editor.py index ba212b513a..49c884e082 100644 --- a/cms/djangoapps/contentstore/features/problem-editor.py +++ b/cms/djangoapps/contentstore/features/problem-editor.py @@ -9,8 +9,6 @@ from common import type_in_codemirror from time import sleep -from pdb import set_trace - DISPLAY_NAME = "Display Name" MAXIMUM_ATTEMPTS = "Maximum Attempts" PROBLEM_WEIGHT = "Problem Weight" diff --git a/cms/static/sass/views/_unit.scss b/cms/static/sass/views/_unit.scss index 7c8a531cdc..2eb3e19173 100644 --- a/cms/static/sass/views/_unit.scss +++ b/cms/static/sass/views/_unit.scss @@ -355,6 +355,19 @@ body.course.unit,.view-unit { } } + + .wrapper-alert-error { + box-shadow: none; + border-top: 5px solid $red-l1; + + .copy, + .title { + color: $white; + } + + } + + } } diff --git a/cms/templates/html_error.html b/cms/templates/html_error.html index f0f82d959b..fec936bb3b 100644 --- a/cms/templates/html_error.html +++ b/cms/templates/html_error.html @@ -1,6 +1,5 @@ <%! from django.utils.translation import ugettext as _ %> <%! from django.core.urlresolvers import reverse %> -<%block name="bodyclass">error <%block name="content">
@@ -12,11 +11,11 @@ ${_("We're having trouble rendering your component")} -

You can try re-editing your component to check that your syntax is correct.

+

Students will not be able to access this component. Re-edit your component to fix the error.

% if message:

- ${_("Error message:")} + ${_("Error:")} ${message | h}

% endif From b7485fd812290a066eee88ddd8f187af3c9e6450 Mon Sep 17 00:00:00 2001 From: Julian Arni Date: Wed, 9 Oct 2013 14:19:34 -0400 Subject: [PATCH 5/8] Review fixes --- .../component_settings_editor_helpers.py | 8 ++++ .../contentstore/features/import.py | 7 ++- .../features/problem-editor.feature | 4 +- .../contentstore/features/problem-editor.py | 6 +-- cms/djangoapps/contentstore/views/preview.py | 5 +- .../about/overview.html | 47 ------------------- .../chapter/Week_1.xml | 3 -- .../data/get_html_exception_test/course.xml | 1 - .../get_html_exception_test/course/hakj.xml | 3 -- .../get_html_exception_test/custom_tags/book | 1 - .../custom_tags/discuss | 1 - .../custom_tags/handout | 1 - .../get_html_exception_test/custom_tags/image | 1 - .../get_html_exception_test/custom_tags/link | 1 - .../custom_tags/slides | 1 - .../policies/assets.json | 1 - .../policies/hakj/grading_policy.json | 1 - .../policies/hakj/policy.json | 1 - .../8af0ab4186c04c2eb08a92926e36d1ce.xml | 3 -- .../vertical/vertical_74cca8afc761.xml | 3 -- 20 files changed, 18 insertions(+), 81 deletions(-) delete mode 100644 common/test/data/get_html_exception_test/about/overview.html delete mode 100644 common/test/data/get_html_exception_test/chapter/Week_1.xml delete mode 100644 common/test/data/get_html_exception_test/course.xml delete mode 100644 common/test/data/get_html_exception_test/course/hakj.xml delete mode 100644 common/test/data/get_html_exception_test/custom_tags/book delete mode 100644 common/test/data/get_html_exception_test/custom_tags/discuss delete mode 100644 common/test/data/get_html_exception_test/custom_tags/handout delete mode 100644 common/test/data/get_html_exception_test/custom_tags/image delete mode 100644 common/test/data/get_html_exception_test/custom_tags/link delete mode 100644 common/test/data/get_html_exception_test/custom_tags/slides delete mode 100644 common/test/data/get_html_exception_test/policies/assets.json delete mode 100644 common/test/data/get_html_exception_test/policies/hakj/grading_policy.json delete mode 100644 common/test/data/get_html_exception_test/policies/hakj/policy.json delete mode 100644 common/test/data/get_html_exception_test/sequential/8af0ab4186c04c2eb08a92926e36d1ce.xml delete mode 100644 common/test/data/get_html_exception_test/vertical/vertical_74cca8afc761.xml diff --git a/cms/djangoapps/contentstore/features/component_settings_editor_helpers.py b/cms/djangoapps/contentstore/features/component_settings_editor_helpers.py index 45fc568f23..9881290eba 100644 --- a/cms/djangoapps/contentstore/features/component_settings_editor_helpers.py +++ b/cms/djangoapps/contentstore/features/component_settings_editor_helpers.py @@ -39,6 +39,7 @@ def click_new_component_button(step, component_button_css): ) world.css_click(component_button_css) + @world.absorb def click_component_from_menu(category, boilerplate, expected_css): """ @@ -63,11 +64,13 @@ def edit_component_and_select_settings(): world.css_click('a.edit-button') world.css_click('#settings-mode a') + @world.absorb def edit_component(): world.wait_for(lambda _driver: world.css_visible('a.edit-button')) world.css_click('a.edit-button') + @world.absorb def verify_setting_entry(setting, display_name, value, explicitly_set): """ @@ -97,6 +100,7 @@ def verify_setting_entry(setting, display_name, value, explicitly_set): assert_equal(explicitly_set, settingClearButton.has_class('active')) assert_equal(not explicitly_set, settingClearButton.has_class('inactive')) + @world.absorb def verify_all_setting_entries(expected_entries): settings = world.browser.find_by_css('.wrapper-comp-setting') @@ -107,6 +111,7 @@ def verify_all_setting_entries(expected_entries): expected_entries[counter][1], expected_entries[counter][2] ) + @world.absorb def save_component_and_reopen(step): world.css_click("a.save-button") @@ -116,6 +121,7 @@ def save_component_and_reopen(step): reload_the_page(step) edit_component_and_select_settings() + @world.absorb def cancel_component(step): world.css_click("a.cancel-button") @@ -123,10 +129,12 @@ def cancel_component(step): # they are not persisted. Refresh the browser to make sure the changes were not persisted. reload_the_page(step) + @world.absorb def revert_setting_entry(label): get_setting_entry(label).find_by_css('.setting-clear')[0].click() + @world.absorb def get_setting_entry(label): def get_setting(): diff --git a/cms/djangoapps/contentstore/features/import.py b/cms/djangoapps/contentstore/features/import.py index 1efb40e974..d1dec5da4c 100644 --- a/cms/djangoapps/contentstore/features/import.py +++ b/cms/djangoapps/contentstore/features/import.py @@ -9,14 +9,13 @@ def import_file(filename): world.browser.attach_file('course-data', os.path.abspath(path)) world.css_click('input.submit-button') # Go to course outline - menu_css = 'li.nav-course-courseware' + world.click_course_content() outline_css = 'li.nav-course-courseware-outline a' - world.css_click(menu_css) world.css_click(outline_css) + @world.absorb def go_to_import(): - menu_css = 'li.nav-course-tools' + world.click_course_content() import_css = 'li.nav-course-tools-import a' - world.css_click(menu_css) world.css_click(import_css) diff --git a/cms/djangoapps/contentstore/features/problem-editor.feature b/cms/djangoapps/contentstore/features/problem-editor.feature index e73bdee81b..2a8f231e16 100644 --- a/cms/djangoapps/contentstore/features/problem-editor.feature +++ b/cms/djangoapps/contentstore/features/problem-editor.feature @@ -3,7 +3,7 @@ Feature: CMS.Problem Editor As a course author, I want to be able to create problems and edit their settings. Scenario: User can view metadata - Given I have an empty course + Given I have created a Blank Common Problem When I edit and select Settings Then I see the advanced settings and their expected values And Edit High Level Source is not visible @@ -91,7 +91,7 @@ Feature: CMS.Problem Editor And when I view the High Level Source I see my changes Scenario: Exceptions don't cause problem to be uneditable (bug STUD-786) - Given I have created a Blank Common Problem + Given I have an empty course And I go to the import page And I import the file "get_html_exception_test.tar.gz" When I go to the unit "Probability and BMI" diff --git a/cms/djangoapps/contentstore/features/problem-editor.py b/cms/djangoapps/contentstore/features/problem-editor.py index 49c884e082..3b614bc028 100644 --- a/cms/djangoapps/contentstore/features/problem-editor.py +++ b/cms/djangoapps/contentstore/features/problem-editor.py @@ -6,7 +6,6 @@ import json from lettuce import world, step from nose.tools import assert_equal, assert_true # pylint: disable=E0611 from common import type_in_codemirror -from time import sleep DISPLAY_NAME = "Display Name" @@ -199,10 +198,12 @@ def high_level_source_in_editor(_step): open_high_level_source() assert_equal('hi', world.css_value('.source-edit-box')) + @step(u'I have an empty course') def i_have_empty_course(step): step.given('I have clicked the new unit button') + @step(u'I go to the import page') def i_go_to_import(_step): world.go_to_import() @@ -215,7 +216,6 @@ def i_import_the_file(_step, filename): @step(u'I click on the link "([^"]*)"$') def i_click_on(_step, link): - #go = "$(\"a:contains('{0}')\").click()".format(link) world.browser.click_link_by_text(link) @@ -232,7 +232,7 @@ def i_go_to_unit(_step, unit): @step(u'I see a message that says "([^"]*)"$') def i_can_see_message(_step, msg): - msg = json.dumps(msg) # escape quotes + msg = json.dumps(msg) # escape quotes world.browser.is_text_present(msg) diff --git a/cms/djangoapps/contentstore/views/preview.py b/cms/djangoapps/contentstore/views/preview.py index 22a0af8171..5aec46c5d7 100644 --- a/cms/djangoapps/contentstore/views/preview.py +++ b/cms/djangoapps/contentstore/views/preview.py @@ -79,13 +79,12 @@ def preview_component(request, location): # can bind to it correctly component.runtime.wrappers.append(partial(wrap_xmodule, 'xmodule_edit.html')) - try: content = component.render('studio_view').content # catch exceptions indiscriminately, since after this point they escape the # dungeon and surface as uneditable, unsaveable, and undeletable # component-goblins. - except Exception as exc: #pylint: disable=W0703 + except Exception as exc: # pylint: disable=W0703 content = render_to_string('html_error.html', {'message': str(exc)}) return render_to_response('component.html', { @@ -168,6 +167,6 @@ def get_preview_html(request, descriptor, idx): module = load_preview_module(request, str(idx), descriptor) try: content = module.render("student_view").content - except Exception as exc: #pylint: disable=W0703 + except Exception as exc: # pylint: disable=W0703 content = render_to_string('html_error.html', {'message': str(exc)}) return content diff --git a/common/test/data/get_html_exception_test/about/overview.html b/common/test/data/get_html_exception_test/about/overview.html deleted file mode 100644 index 961786b8f4..0000000000 --- a/common/test/data/get_html_exception_test/about/overview.html +++ /dev/null @@ -1,47 +0,0 @@ -
-

About This Course

-

Include your long course description here. The long course description should contain 150-400 words.

- -

This is paragraph 2 of the long course description. Add more paragraphs as needed. Make sure to enclose them in paragraph tags.

-
- -
-

Prerequisites

-

Add information about course prerequisites here.

-
- -
-

Course Staff

-
-
- -
- -

Staff Member #1

-

Biography of instructor/staff member #1

-
- -
-
- -
- -

Staff Member #2

-

Biography of instructor/staff member #2

-
-
- -
-
-

Frequently Asked Questions

-
-

Do I need to buy a textbook?

-

No, a free online version of Chemistry: Principles, Patterns, and Applications, First Edition by Bruce Averill and Patricia Eldredge will be available, though you can purchase a printed version (published by FlatWorld Knowledge) if you’d like.

-
- -
-

Question #2

-

Your answer would be displayed here.

-
-
-
diff --git a/common/test/data/get_html_exception_test/chapter/Week_1.xml b/common/test/data/get_html_exception_test/chapter/Week_1.xml deleted file mode 100644 index c6e1295a69..0000000000 --- a/common/test/data/get_html_exception_test/chapter/Week_1.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/common/test/data/get_html_exception_test/course.xml b/common/test/data/get_html_exception_test/course.xml deleted file mode 100644 index bedccb4153..0000000000 --- a/common/test/data/get_html_exception_test/course.xml +++ /dev/null @@ -1 +0,0 @@ - diff --git a/common/test/data/get_html_exception_test/course/hakj.xml b/common/test/data/get_html_exception_test/course/hakj.xml deleted file mode 100644 index cd83c98bac..0000000000 --- a/common/test/data/get_html_exception_test/course/hakj.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/common/test/data/get_html_exception_test/custom_tags/book b/common/test/data/get_html_exception_test/custom_tags/book deleted file mode 100644 index 8b13789179..0000000000 --- a/common/test/data/get_html_exception_test/custom_tags/book +++ /dev/null @@ -1 +0,0 @@ - diff --git a/common/test/data/get_html_exception_test/custom_tags/discuss b/common/test/data/get_html_exception_test/custom_tags/discuss deleted file mode 100644 index ac56590074..0000000000 --- a/common/test/data/get_html_exception_test/custom_tags/discuss +++ /dev/null @@ -1 +0,0 @@ - Discussion: ${tag} \ No newline at end of file diff --git a/common/test/data/get_html_exception_test/custom_tags/handout b/common/test/data/get_html_exception_test/custom_tags/handout deleted file mode 100644 index 014e6f3305..0000000000 --- a/common/test/data/get_html_exception_test/custom_tags/handout +++ /dev/null @@ -1 +0,0 @@ - ${text_of_link} diff --git a/common/test/data/get_html_exception_test/custom_tags/image b/common/test/data/get_html_exception_test/custom_tags/image deleted file mode 100644 index d2939ba88c..0000000000 --- a/common/test/data/get_html_exception_test/custom_tags/image +++ /dev/null @@ -1 +0,0 @@ - diff --git a/common/test/data/get_html_exception_test/custom_tags/link b/common/test/data/get_html_exception_test/custom_tags/link deleted file mode 100644 index e389844059..0000000000 --- a/common/test/data/get_html_exception_test/custom_tags/link +++ /dev/null @@ -1 +0,0 @@ - ${text_of_link} diff --git a/common/test/data/get_html_exception_test/custom_tags/slides b/common/test/data/get_html_exception_test/custom_tags/slides deleted file mode 100644 index 7a33ffd6c7..0000000000 --- a/common/test/data/get_html_exception_test/custom_tags/slides +++ /dev/null @@ -1 +0,0 @@ -Lecture Slides Handout [Clean ][Annotated] \ No newline at end of file diff --git a/common/test/data/get_html_exception_test/policies/assets.json b/common/test/data/get_html_exception_test/policies/assets.json deleted file mode 100644 index 9e26dfeeb6..0000000000 --- a/common/test/data/get_html_exception_test/policies/assets.json +++ /dev/null @@ -1 +0,0 @@ -{} \ No newline at end of file diff --git a/common/test/data/get_html_exception_test/policies/hakj/grading_policy.json b/common/test/data/get_html_exception_test/policies/hakj/grading_policy.json deleted file mode 100644 index 272cb4fec6..0000000000 --- a/common/test/data/get_html_exception_test/policies/hakj/grading_policy.json +++ /dev/null @@ -1 +0,0 @@ -{"GRADER": [{"short_label": "HW", "min_count": 12, "type": "Homework", "drop_count": 2, "weight": 0.15}, {"min_count": 12, "type": "Lab", "drop_count": 2, "weight": 0.15}, {"short_label": "Midterm", "min_count": 1, "type": "Midterm Exam", "drop_count": 0, "weight": 0.3}, {"short_label": "Final", "min_count": 1, "type": "Final Exam", "drop_count": 0, "weight": 0.4}], "GRADE_CUTOFFS": {"Pass": 0.5}} \ No newline at end of file diff --git a/common/test/data/get_html_exception_test/policies/hakj/policy.json b/common/test/data/get_html_exception_test/policies/hakj/policy.json deleted file mode 100644 index defbd8245d..0000000000 --- a/common/test/data/get_html_exception_test/policies/hakj/policy.json +++ /dev/null @@ -1 +0,0 @@ -{"course/hakj": {"ispublic": false, "graded": false, "tabs": [{"type": "courseware"}, {"type": "course_info", "name": "Course Info"}, {"type": "textbooks"}, {"type": "discussion", "name": "Discussion"}, {"type": "wiki", "name": "Wiki"}, {"type": "progress", "name": "Progress"}], "remote_gradebook": {}, "giturl": null, "discussion_topics": {"General": {"id": "i4x-edx-ctt101-course-html_exception_test"}}, "due": null, "source_file": null, "html_textbooks": [], "announcement": null, "showanswer": "attempted", "display_name": "Principles of Biostatistics", "graceperiod": "900 seconds", "allow_anonymous": false, "tags": [], "enrollment_start": "2013-08-26T04:00:00Z", "start": "2013-08-26T04:00:00Z", "xml_attributes": {"filename": ["course/html_exception_test.xml", "course/html_exception_test.xml"]}, "pdf_textbooks": [], "days_early_for_beta": 100, "advanced_modules": [], "format": null, "xqa_key": "AlQ7TjCl7Rfhc0Am6WguqjeUzGz7AuVt", "enrollment_end": "2013-09-25T04:00:00Z", "end": "2013-12-20T05:00:00Z", "show_calculator": "Yes", "hide_from_toc": false, "rerandomize": "never", "cohort_config": {}}} \ No newline at end of file diff --git a/common/test/data/get_html_exception_test/sequential/8af0ab4186c04c2eb08a92926e36d1ce.xml b/common/test/data/get_html_exception_test/sequential/8af0ab4186c04c2eb08a92926e36d1ce.xml deleted file mode 100644 index 5885a6ae5c..0000000000 --- a/common/test/data/get_html_exception_test/sequential/8af0ab4186c04c2eb08a92926e36d1ce.xml +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/common/test/data/get_html_exception_test/vertical/vertical_74cca8afc761.xml b/common/test/data/get_html_exception_test/vertical/vertical_74cca8afc761.xml deleted file mode 100644 index 7a02d7565c..0000000000 --- a/common/test/data/get_html_exception_test/vertical/vertical_74cca8afc761.xml +++ /dev/null @@ -1,3 +0,0 @@ - - PDF of Problem Set 3 - From de1ee17323707baa9af99ae83f353ae4681e9b72 Mon Sep 17 00:00:00 2001 From: Frances Botsford Date: Wed, 9 Oct 2013 14:26:32 -0400 Subject: [PATCH 6/8] fixing alignment error on studio component error message, i18n error message --- cms/static/sass/views/_unit.scss | 1 + cms/templates/html_error.html | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/cms/static/sass/views/_unit.scss b/cms/static/sass/views/_unit.scss index 2eb3e19173..50685123a2 100644 --- a/cms/static/sass/views/_unit.scss +++ b/cms/static/sass/views/_unit.scss @@ -357,6 +357,7 @@ body.course.unit,.view-unit { } .wrapper-alert-error { + margin-top: ($baseline*1.25); box-shadow: none; border-top: 5px solid $red-l1; diff --git a/cms/templates/html_error.html b/cms/templates/html_error.html index fec936bb3b..65bf870029 100644 --- a/cms/templates/html_error.html +++ b/cms/templates/html_error.html @@ -11,7 +11,7 @@ ${_("We're having trouble rendering your component")} -

Students will not be able to access this component. Re-edit your component to fix the error.

+

${_("Students will not be able to access this component. Re-edit your component to fix the error.")}

% if message:

From 9798da413d026c584ed191c96110d7540550220b Mon Sep 17 00:00:00 2001 From: Julian Arni Date: Wed, 9 Oct 2013 16:32:32 -0400 Subject: [PATCH 7/8] Review fixes --- cms/djangoapps/contentstore/features/import.py | 3 ++- cms/djangoapps/contentstore/features/problem-editor.py | 10 +++------- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/cms/djangoapps/contentstore/features/import.py b/cms/djangoapps/contentstore/features/import.py index d1dec5da4c..511d2e7246 100644 --- a/cms/djangoapps/contentstore/features/import.py +++ b/cms/djangoapps/contentstore/features/import.py @@ -16,6 +16,7 @@ def import_file(filename): @world.absorb def go_to_import(): - world.click_course_content() + menu_css = 'li.nav-course-tools' import_css = 'li.nav-course-tools-import a' + world.css_click(menu_css) world.css_click(import_css) diff --git a/cms/djangoapps/contentstore/features/problem-editor.py b/cms/djangoapps/contentstore/features/problem-editor.py index 3b614bc028..9316329cf9 100644 --- a/cms/djangoapps/contentstore/features/problem-editor.py +++ b/cms/djangoapps/contentstore/features/problem-editor.py @@ -5,7 +5,7 @@ import os import json from lettuce import world, step from nose.tools import assert_equal, assert_true # pylint: disable=E0611 -from common import type_in_codemirror +from common import type_in_codemirror, open_new_course DISPLAY_NAME = "Display Name" @@ -201,7 +201,7 @@ def high_level_source_in_editor(_step): @step(u'I have an empty course') def i_have_empty_course(step): - step.given('I have clicked the new unit button') + open_new_course() @step(u'I go to the import page') @@ -238,11 +238,7 @@ def i_can_see_message(_step, msg): @step(u'I can edit the problem$') def i_can_edit_problem(_step): - try: - world.edit_component() - except TimeoutException: - assert_true(False) - assert_true(True) + world.edit_component() def verify_high_level_source_links(step, visible): From d9ba410388b7f1c65397e66e11e393e0401e9bb4 Mon Sep 17 00:00:00 2001 From: Julian Arni Date: Thu, 10 Oct 2013 15:13:14 -0400 Subject: [PATCH 8/8] Review fixes --- .../features/{import.py => course_import.py} | 2 -- .../contentstore/features/problem-editor.feature | 2 +- .../contentstore/features/problem-editor.py | 13 +++++++------ cms/djangoapps/contentstore/views/import_export.py | 4 +--- 4 files changed, 9 insertions(+), 12 deletions(-) rename cms/djangoapps/contentstore/features/{import.py => course_import.py} (96%) diff --git a/cms/djangoapps/contentstore/features/import.py b/cms/djangoapps/contentstore/features/course_import.py similarity index 96% rename from cms/djangoapps/contentstore/features/import.py rename to cms/djangoapps/contentstore/features/course_import.py index 511d2e7246..0d26124d79 100644 --- a/cms/djangoapps/contentstore/features/import.py +++ b/cms/djangoapps/contentstore/features/course_import.py @@ -2,7 +2,6 @@ import os from lettuce import world from django.conf import settings -@world.absorb def import_file(filename): world.browser.execute_script("$('input.file-input').css('display', 'block')") path = os.path.join(settings.COMMON_TEST_DATA_ROOT, "imports", filename) @@ -14,7 +13,6 @@ def import_file(filename): world.css_click(outline_css) -@world.absorb def go_to_import(): menu_css = 'li.nav-course-tools' import_css = 'li.nav-course-tools-import a' diff --git a/cms/djangoapps/contentstore/features/problem-editor.feature b/cms/djangoapps/contentstore/features/problem-editor.feature index 2a8f231e16..f3b75ebf7e 100644 --- a/cms/djangoapps/contentstore/features/problem-editor.feature +++ b/cms/djangoapps/contentstore/features/problem-editor.feature @@ -95,7 +95,7 @@ Feature: CMS.Problem Editor And I go to the import page And I import the file "get_html_exception_test.tar.gz" When I go to the unit "Probability and BMI" - And I click on the link "edit a draft" + And I click on "edit a draft" Then I see a message that says "We're having trouble rendering your component" And I can edit the problem diff --git a/cms/djangoapps/contentstore/features/problem-editor.py b/cms/djangoapps/contentstore/features/problem-editor.py index 9316329cf9..262d1bfc10 100644 --- a/cms/djangoapps/contentstore/features/problem-editor.py +++ b/cms/djangoapps/contentstore/features/problem-editor.py @@ -6,6 +6,7 @@ import json from lettuce import world, step from nose.tools import assert_equal, assert_true # pylint: disable=E0611 from common import type_in_codemirror, open_new_course +from course_import import import_file, go_to_import DISPLAY_NAME = "Display Name" @@ -206,17 +207,17 @@ def i_have_empty_course(step): @step(u'I go to the import page') def i_go_to_import(_step): - world.go_to_import() + go_to_import() @step(u'I import the file "([^"]*)"$') def i_import_the_file(_step, filename): - world.import_file(filename) + import_file(filename) -@step(u'I click on the link "([^"]*)"$') -def i_click_on(_step, link): - world.browser.click_link_by_text(link) +@step(u'I click on "edit a draft"$') +def i_edit_a_draft(_step): + world.css_click("a.create-draft") @step(u'I go to the vertical "([^"]*)"$') @@ -233,7 +234,7 @@ def i_go_to_unit(_step, unit): @step(u'I see a message that says "([^"]*)"$') def i_can_see_message(_step, msg): msg = json.dumps(msg) # escape quotes - world.browser.is_text_present(msg) + world.css_has_text("h2.title", msg) @step(u'I can edit the problem$') diff --git a/cms/djangoapps/contentstore/views/import_export.py b/cms/djangoapps/contentstore/views/import_export.py index aa4fa6b606..6252da0d0e 100644 --- a/cms/djangoapps/contentstore/views/import_export.py +++ b/cms/djangoapps/contentstore/views/import_export.py @@ -35,8 +35,6 @@ from .access import get_location_and_verify_access from util.json_request import JsonResponse from extract_tar import safetar_extractall -import traceback - __all__ = ['import_course', 'import_status', 'generate_export_course', 'export_course'] @@ -230,7 +228,7 @@ def import_course(request, org, course, name): except Exception as exception: # pylint: disable=W0703 return JsonResponse( { - 'ErrMsg': str(exception) + traceback.format_exc(), + 'ErrMsg': str(exception), 'Stage': session_status[key] }, status=400