diff --git a/cms/static/cms/js/require-config.js b/cms/static/cms/js/require-config.js index 05c935425f..1755ac4bb4 100644 --- a/cms/static/cms/js/require-config.js +++ b/cms/static/cms/js/require-config.js @@ -95,7 +95,7 @@ // end of Annotation tool files // externally hosted files - mathjax: '//cdn.mathjax.org/mathjax/2.6-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured', // eslint-disable-line max-len + mathjax: '//cdn.mathjax.org/mathjax/2.7-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured', // eslint-disable-line max-len 'youtube': [ // youtube URL does not end in '.js'. We add '?noext' to the path so // that require.js adds the '.js' to the query component of the URL, diff --git a/cms/static/cms/js/spec/main.js b/cms/static/cms/js/spec/main.js index 1490f36faf..26b09c9c3a 100644 --- a/cms/static/cms/js/spec/main.js +++ b/cms/static/cms/js/spec/main.js @@ -55,7 +55,7 @@ 'domReady': 'xmodule_js/common_static/js/vendor/domReady', 'URI': 'xmodule_js/common_static/js/vendor/URI.min', 'mock-ajax': 'xmodule_js/common_static/js/vendor/mock-ajax', - mathjax: '//cdn.mathjax.org/mathjax/2.6-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured', // eslint-disable-line max-len + mathjax: '//cdn.mathjax.org/mathjax/2.7-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured', // eslint-disable-line max-len 'youtube': '//www.youtube.com/player_api?noext', 'coffee/src/ajax_prefix': 'xmodule_js/common_static/coffee/src/ajax_prefix', 'js/spec/test_utils': 'js/spec/test_utils' diff --git a/cms/static/cms/js/spec/main_squire.js b/cms/static/cms/js/spec/main_squire.js index b4eb462775..49850e0999 100644 --- a/cms/static/cms/js/spec/main_squire.js +++ b/cms/static/cms/js/spec/main_squire.js @@ -48,7 +48,7 @@ 'draggabilly': 'xmodule_js/common_static/js/vendor/draggabilly', 'domReady': 'xmodule_js/common_static/js/vendor/domReady', 'URI': 'xmodule_js/common_static/js/vendor/URI.min', - mathjax: '//cdn.mathjax.org/mathjax/2.6-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured', // eslint-disable-line max-len + mathjax: '//cdn.mathjax.org/mathjax/2.7-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured', // eslint-disable-line max-len 'youtube': '//www.youtube.com/player_api?noext', 'coffee/src/ajax_prefix': 'xmodule_js/common_static/coffee/src/ajax_prefix' }, diff --git a/common/lib/xmodule/xmodule/css/capa/display.scss b/common/lib/xmodule/xmodule/css/capa/display.scss index 2d0fd65ccf..8e24e08b66 100644 --- a/common/lib/xmodule/xmodule/css/capa/display.scss +++ b/common/lib/xmodule/xmodule/css/capa/display.scss @@ -975,7 +975,7 @@ div.problem .action { } .submit { @include margin-right($baseline / 2); - float: left; + @include float(left); } } diff --git a/common/static/common/js/discussion/mathjax_include.js b/common/static/common/js/discussion/mathjax_include.js index 942dc54b58..34594f86ca 100644 --- a/common/static/common/js/discussion/mathjax_include.js +++ b/common/static/common/js/discussion/mathjax_include.js @@ -42,6 +42,6 @@ if (typeof MathJax === 'undefined') { }); }; }; - vendorScript.src = 'https://cdn.mathjax.org/mathjax/2.6-latest/MathJax.js?config=TeX-MML-AM_SVG'; + vendorScript.src = 'https://cdn.mathjax.org/mathjax/2.7-latest/MathJax.js?config=TeX-MML-AM_SVG'; document.body.appendChild(vendorScript); } diff --git a/common/templates/mathjax_include.html b/common/templates/mathjax_include.html index c41818c3e5..7c8d0c99ca 100644 --- a/common/templates/mathjax_include.html +++ b/common/templates/mathjax_include.html @@ -76,4 +76,4 @@ - + diff --git a/common/test/acceptance/pages/lms/teams.py b/common/test/acceptance/pages/lms/teams.py index 4a06c5905a..d8722f15c2 100644 --- a/common/test/acceptance/pages/lms/teams.py +++ b/common/test/acceptance/pages/lms/teams.py @@ -6,7 +6,7 @@ Teams pages. from common.test.acceptance.pages.lms.course_page import CoursePage from common.test.acceptance.pages.lms.discussion import InlineDiscussionPage from common.test.acceptance.pages.common.paging import PaginatedUIMixin -from common.test.acceptance.pages.common.utils import confirm_prompt +from common.test.acceptance.pages.common.utils import confirm_prompt, click_css from common.test.acceptance.pages.lms.fields import FieldsMixin @@ -502,7 +502,7 @@ class TeamPage(CoursePage, PaginatedUIMixin, BreadcrumbsMixin): def click_leave_team_link(self, remaining_members=0, cancel=False): """ Click on Leave Team link""" - self.q(css='.leave-team-link').first.click() + click_css(self, '.leave-team-link', require_notification=False) confirm_prompt(self, cancel, require_notification=False) if cancel is False: diff --git a/common/test/acceptance/tests/lms/test_teams.py b/common/test/acceptance/tests/lms/test_teams.py index 41e376cd94..6983f72096 100644 --- a/common/test/acceptance/tests/lms/test_teams.py +++ b/common/test/acceptance/tests/lms/test_teams.py @@ -1042,8 +1042,21 @@ class CreateTeamTest(TeamFormActions): Then I should see the error message and highlighted fields. """ self.verify_and_navigate_to_create_team_page() - self.team_management_page.submit_form() + # `submit_form` clicks on a button, but that button doesn't always + # have the click event handler registered on it in time. That's why + # this test is flaky. Unfortunately, I don't know of a straightforward + # way to write something that waits for that event handler to be bound + # to the button element. So I used time.sleep as well, even though + # the bok choy docs explicitly ask us not to: + # http://bok-choy.readthedocs.io/en/latest/guidelines.html + # Sorry! For the story to address this anti-pattern, see TNL-5820 + time.sleep(0.5) + self.team_management_page.submit_form() + self.team_management_page.wait_for( + lambda: self.team_management_page.validation_message_text, + "Validation message text never loaded." + ) self.assertEqual( self.team_management_page.validation_message_text, 'Check the highlighted fields below and try again.' @@ -1150,6 +1163,13 @@ class CreateTeamTest(TeamFormActions): self.assertTrue(self.browse_teams_page.get_pagination_header_text().startswith('Showing 0 out of 0 total')) self.verify_and_navigate_to_create_team_page() + + # We add a sleep here to allow time for the click event handler to bind + # to the cancel button. Using time.sleep in bok-choy tests is, + # generally, an anti-pattern. So don't copy this :). + # For the story to address this anti-pattern, see TNL-5820 + time.sleep(0.5) + self.team_management_page.cancel_team() self.assertTrue(self.browse_teams_page.is_browser_on_page()) @@ -1940,6 +1960,13 @@ class TeamPageTest(TeamsTabBase): } ] with self.assert_events_match_during(event_filter=self.only_team_events, expected_events=expected_events): + # I think we're seeing the same problem that we're seeing in + # CreateTeamTest.test_user_can_see_error_message_for_missing_data. + # We click on the "leave team" link after it's loaded, but before + # its JavaScript event handler is added. Adding this sleep gives + # enough time for that event handler to bind to the link. Sorry! + # For the story to address this anti-pattern, see TNL-5820 + time.sleep(0.5) self.team_page.click_leave_team_link() self.assert_team_details(num_members=0, is_member=False) self.assertTrue(self.team_page.join_team_button_present) diff --git a/lms/static/js/instructor_dashboard/membership.js b/lms/static/js/instructor_dashboard/membership.js index e45bb8998b..94b104ad26 100644 --- a/lms/static/js/instructor_dashboard/membership.js +++ b/lms/static/js/instructor_dashboard/membership.js @@ -12,7 +12,11 @@ such that the value can be defined later than this assignment (file load order). (function() { 'use strict'; var AuthListWidget, BatchEnrollment, BetaTesterBulkAddition, - MemberListWidget, Membership, emailStudents, plantTimeout, statusAjaxError; + MemberListWidget, Membership, emailStudents, plantTimeout, statusAjaxError, + /* eslint-disable */ + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + /* eslint-enable */ plantTimeout = function() { return window.InstructorDashboard.util.plantTimeout.apply(this, arguments); @@ -38,10 +42,8 @@ such that the value can be defined later than this assignment (file load order). add_btn_label: 'Add Member', add_handler: function() {} }); - templateHtml = $('#member-list-widget-template').html(); - edx.HtmlUtils.setHtml( - this.$container, window.Mustache.render(templateHtml, edx.HtmlUtils.HTML(memberListParams)) - ); + templateHtml = window.Mustache.render($('#member-list-widget-template').html(), memberListParams); + edx.HtmlUtils.setHtml(this.$container, edx.HtmlUtils.HTML(templateHtml)); this.$('input[type="button"].add').click(function() { condition = typeof memberListParams.add_handler === 'function'; return condition ? memberListParams.add_handler(memberlistwidget.$('.add-field').val()) : undefined; @@ -64,7 +66,7 @@ such that the value can be defined later than this assignment (file load order). item = rowArray[i]; $td = $(''); if (item instanceof jQuery) { - edx.HtmlUtils.append($td, item); + edx.HtmlUtils.append($td, edx.HtmlUtils.HTML(item)); } else { $td.text(item); } @@ -86,13 +88,14 @@ such that the value can be defined later than this assignment (file load order). return memberListWidget; }()); - AuthListWidget = (function() { - function authListWidget($container, rolename, $errorSection) { + AuthListWidget = (function(_super) { + __extends(AuthListWidget, _super); // eslint-disable-line no-use-before-define + function AuthListWidget($container, rolename, $errorSection) { // eslint-disable-line no-shadow var msg, authlistwidget = this; this.rolename = rolename; this.$errorSection = $errorSection; - authListWidget.super.constructor.call(this, $container, { + AuthListWidget.__super__.constructor.call(this, $container, { // eslint-disable-line no-underscore-dangle title: $container.data('display-name'), info: $container.data('info-text'), labels: [gettext('Username'), gettext('Email'), gettext('Revoke access')], @@ -112,13 +115,13 @@ such that the value can be defined later than this assignment (file load order). this.reload_list(); } - authListWidget.prototype.re_view = function() { + AuthListWidget.prototype.re_view = function() { this.clear_errors(); this.clear_input(); return this.reload_list(); }; - authListWidget.prototype.add_handler = function(input) { + AuthListWidget.prototype.add_handler = function(input) { var authlistwidgetaddhandler = this; if ((input != null) && input !== '') { return this.modify_member_access(input, 'allow', function(error) { @@ -134,7 +137,7 @@ such that the value can be defined later than this assignment (file load order). } }; - authListWidget.prototype.reload_list = function() { + AuthListWidget.prototype.reload_list = function() { var authlistwidgetreloadlist = this; return this.get_member_list(function(error, memberList) { if (error !== null) { @@ -163,19 +166,19 @@ such that the value can be defined later than this assignment (file load order). }); }; - authListWidget.prototype.clear_errors = function() { + AuthListWidget.prototype.clear_errors = function() { var ref, result; result = (this.$error_section) != null ? ref.text('') : undefined; return result; }; - authListWidget.prototype.show_errors = function(msg) { + AuthListWidget.prototype.show_errors = function(msg) { var ref, result; result = (this.$error_section) != null ? ref.text(msg) : undefined; return result; }; - authListWidget.prototype.get_member_list = function(cb) { + AuthListWidget.prototype.get_member_list = function(cb) { var authlistwidgetgetmemberlist = this; return $.ajax({ type: 'POST', @@ -190,7 +193,7 @@ such that the value can be defined later than this assignment (file load order). }); }; - authListWidget.prototype.modify_member_access = function(uniqueStudentIdentifier, action, cb) { + AuthListWidget.prototype.modify_member_access = function(uniqueStudentIdentifier, action, cb) { var authlistwidgetmemberaccess = this; return $.ajax({ type: 'POST', @@ -210,7 +213,7 @@ such that the value can be defined later than this assignment (file load order). }); }; - authListWidget.prototype.member_response = function(data) { + AuthListWidget.prototype.member_response = function(data) { var msg; this.clear_errors(); this.clear_input(); @@ -233,7 +236,7 @@ such that the value can be defined later than this assignment (file load order). } }; - return authListWidget; + return AuthListWidget; }(MemberListWidget)); this.AutoEnrollmentViaCsv = (function() { diff --git a/lms/static/lms/js/spec/main.js b/lms/static/lms/js/spec/main.js index 85aa5f43ae..2a4b77f506 100644 --- a/lms/static/lms/js/spec/main.js +++ b/lms/static/lms/js/spec/main.js @@ -51,7 +51,7 @@ 'squire': 'xmodule_js/common_static/js/vendor/Squire', 'jasmine-imagediff': 'xmodule_js/common_static/js/vendor/jasmine-imagediff', 'domReady': 'xmodule_js/common_static/js/vendor/domReady', - mathjax: '//cdn.mathjax.org/mathjax/2.6-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured', // eslint-disable-line max-len + mathjax: '//cdn.mathjax.org/mathjax/2.7-latest/MathJax.js?config=TeX-MML-AM_SVG&delayStartupUntil=configured', // eslint-disable-line max-len 'youtube': '//www.youtube.com/player_api?noext', 'coffee/src/ajax_prefix': 'xmodule_js/common_static/coffee/src/ajax_prefix', 'js/instructor_dashboard/student_admin': 'js/instructor_dashboard/student_admin',