Commit f1101a7b by Albert St. Aubin

Update to reduce flakiness of this test set removed flaky annotation

TNL-5582
parent 964588f5
define(['js/views/validation', 'codemirror', 'js/models/course_update', define(['codemirror',
'common/js/components/views/feedback_prompt', 'common/js/components/views/feedback_notification', 'js/utils/modal',
'js/views/course_info_helper', 'js/utils/modal', 'js/utils/date_utils'], 'js/utils/date_utils',
function(ValidatingView, CodeMirror, CourseUpdateModel, PromptView, NotificationView, 'edx-ui-toolkit/js/utils/html-utils',
CourseInfoHelper, ModalUtils, DateUtils) { 'js/views/course_info_helper',
'js/views/validation',
'js/models/course_update',
'common/js/components/views/feedback_prompt',
'common/js/components/views/feedback_notification'],
function(CodeMirror, ModalUtils, DateUtils, HtmlUtils, CourseInfoHelper, ValidatingView, CourseUpdateModel,
PromptView, NotificationView) {
'use strict'; 'use strict';
var CourseInfoUpdateView = ValidatingView.extend({ var CourseInfoUpdateView = ValidatingView.extend({
...@@ -17,32 +23,51 @@ define(['js/views/validation', 'codemirror', 'js/models/course_update', ...@@ -17,32 +23,51 @@ define(['js/views/validation', 'codemirror', 'js/models/course_update',
initialize: function() { initialize: function() {
this.template = this.loadTemplate('course_info_update'); this.template = this.loadTemplate('course_info_update');
this.render();
// when the client refetches the updates as a whole, re-render them // when the client refetches the updates as a whole, re-render them
this.listenTo(this.collection, 'reset', this.render); this.listenTo(this.collection, 'reset', this.render);
this.listenTo(this.collection, 'invalid', this.handleValidationError); this.listenTo(this.collection, 'invalid', this.handleValidationError);
}, },
render: function() { render: function() {
// iterate over updates and create views for each using the template // iterate over updates and create views for each using the template
var updateEle = this.$el.find('#course-update-list'); var updateList = this.$el.find('#course-update-list'),
// remove and then add all children self = this;
$(updateEle).empty(); $(updateList).empty();
var self = this; if (this.collection.length > 0) {
this.collection.each(function(update, index) { this.collection.each(function(update, index) {
try { try {
CourseInfoHelper.changeContentToPreview( CourseInfoHelper.changeContentToPreview(
update, 'content', self.options['base_asset_url']); update, 'content', self.options.base_asset_url);
// push notification is always disabled for existing updates // push notification is always disabled for existing updates
var newEle = self.template({updateModel: update, push_notification_enabled: false}); HtmlUtils.append(
$(updateEle).append(newEle); updateList,
DateUtils.setupDatePicker('date', self, index); HtmlUtils.HTML(self.template({updateModel: update, push_notification_enabled: false}))
update.isValid(); );
} catch (e) { DateUtils.setupDatePicker('date', self, index);
// ignore update.isValid();
} catch (e) {
// ignore
} finally {
if (index === self.collection.length - 1) {
// Once the collection is loaded enable the button.
self.$el.find('.new-update-button').removeAttr('disabled');
}
}
});
} else {
// If the collection is empty enable the New update button
self.$el.find('.new-update-button').removeAttr('disabled');
}
// Hide Update forms that are not for new updates with the editing class
updateList.children().each(function(index, updateElement) {
var $updateElement = $(updateElement);
var updateForm = $updateElement.find('.new-update-form');
if ($updateElement.length > 0 && !$updateElement.hasClass('editing')) {
$(updateForm).hide();
} }
}); });
this.$el.find('.new-update-form').hide();
return this; return this;
}, },
...@@ -70,32 +95,39 @@ define(['js/views/validation', 'codemirror', 'js/models/course_update', ...@@ -70,32 +95,39 @@ define(['js/views/validation', 'codemirror', 'js/models/course_update',
}, },
handleValidationError: function(model, error) { handleValidationError: function(model, error) {
var ele = this.$el.find('#course-update-list li[name=\"' + model.cid + '\"]'); var self = this,
$(ele).find('.message-error').remove(); $validationElement = this.$el.find('#course-update-list li[name="' + model.cid + '"]');
for (var field in error) {
$validationElement.find('.message-error').remove();
Object.keys(error).forEach(function(field) {
if (error.hasOwnProperty(field)) { if (error.hasOwnProperty(field)) {
$(ele).find('#update-date-' + model.cid).parent().append( HtmlUtils.append(
this.errorTemplate({message: error[field]}) $validationElement.find('#update-date-' + model.cid).parent(),
); self.errorTemplate({message: error[field]})
$(ele).find('.date-display').parent().append(this.errorTemplate({message: error[field]})); );
HtmlUtils.append(
$validationElement.find('.date-display').parent(),
self.errorTemplate({message: error[field]})
);
} }
} });
$(ele).find('.save-button').addClass('is-disabled');
$validationElement.find('.save-button').addClass('is-disabled');
}, },
validateModel: function(model) { validateModel: function(model) {
var $validationElement = this.$el.find('#course-update-list li[name="' + model.cid + '"]');
if (model.isValid()) { if (model.isValid()) {
var ele = this.$el.find('#course-update-list li[name=\"' + model.cid + '\"]'); $validationElement.find('.message-error').remove();
$(ele).find('.message-error').remove(); $validationElement.find('.save-button').removeClass('is-disabled');
$(ele).find('.save-button').removeClass('is-disabled');
} }
}, },
onNew: function(event) { onNew: function(event) {
event.preventDefault(); // create new obj, insert into collection, and render this one ele overriding the hidden attr
var self = this;
// create new obj, insert into collection, and render this one ele overriding the hidden attr
var newModel = new CourseUpdateModel(); var newModel = new CourseUpdateModel();
event.preventDefault();
this.collection.add(newModel, {at: 0}); this.collection.add(newModel, {at: 0});
var $newForm = $( var $newForm = $(
...@@ -103,7 +135,7 @@ define(['js/views/validation', 'codemirror', 'js/models/course_update', ...@@ -103,7 +135,7 @@ define(['js/views/validation', 'codemirror', 'js/models/course_update',
updateModel: newModel, updateModel: newModel,
push_notification_enabled: this.options.push_notification_enabled push_notification_enabled: this.options.push_notification_enabled
}) })
); );
var updateEle = this.$el.find('#course-update-list'); var updateEle = this.$el.find('#course-update-list');
$(updateEle).prepend($newForm); $(updateEle).prepend($newForm);
...@@ -118,7 +150,7 @@ define(['js/views/validation', 'codemirror', 'js/models/course_update', ...@@ -118,7 +150,7 @@ define(['js/views/validation', 'codemirror', 'js/models/course_update',
$newForm.addClass('editing'); $newForm.addClass('editing');
this.$currentPost = $newForm.closest('li'); this.$currentPost = $newForm.closest('li');
// Variable stored for unit test. // Variable stored for unit test.
this.$modalCover = ModalUtils.showModalCover(false, function() { this.$modalCover = ModalUtils.showModalCover(false, function() {
// Binding empty function to prevent default hideModal. // Binding empty function to prevent default hideModal.
}); });
...@@ -187,7 +219,7 @@ define(['js/views/validation', 'codemirror', 'js/models/course_update', ...@@ -187,7 +219,7 @@ define(['js/views/validation', 'codemirror', 'js/models/course_update',
$(this.dateEntry(event)).val('MM/DD/YY'); $(this.dateEntry(event)).val('MM/DD/YY');
} }
this.$codeMirror = CourseInfoHelper.editWithCodeMirror( this.$codeMirror = CourseInfoHelper.editWithCodeMirror(
targetModel, 'content', self.options['base_asset_url'], $textArea.get(0)); targetModel, 'content', self.options.base_asset_url, $textArea.get(0));
// Variable stored for unit test. // Variable stored for unit test.
this.$modalCover = ModalUtils.showModalCover(false, this.$modalCover = ModalUtils.showModalCover(false,
...@@ -222,12 +254,12 @@ define(['js/views/validation', 'codemirror', 'js/models/course_update', ...@@ -222,12 +254,12 @@ define(['js/views/validation', 'codemirror', 'js/models/course_update',
}); });
deleting.show(); deleting.show();
targetModel.destroy({ targetModel.destroy({
success: function(model, response) { success: function() {
self.collection.fetch({ self.collection.fetch({
success: function() { success: function() {
self.render(); self.render();
deleting.hide(); deleting.hide();
}, },
reset: true reset: true
}); });
} }
...@@ -247,24 +279,25 @@ define(['js/views/validation', 'codemirror', 'js/models/course_update', ...@@ -247,24 +279,25 @@ define(['js/views/validation', 'codemirror', 'js/models/course_update',
}, },
closeEditor: function(removePost) { closeEditor: function(removePost) {
var targetModel = this.collection.get(this.$currentPost.attr('name')); var content,
targetModel = this.collection.get(this.$currentPost.attr('name'));
// If the model was never created (user created a new update, then pressed Cancel), // If the model was never created (user created a new update, then pressed Cancel),
// we wish to remove it from the DOM. // we wish to remove it from the DOM.
if (removePost) { if (removePost) {
this.$currentPost.remove(); this.$currentPost.remove();
} } else {
else {
// close the modal and insert the appropriate data // close the modal and insert the appropriate data
this.$currentPost.removeClass('editing'); this.$currentPost.removeClass('editing');
this.$currentPost.find('.date-display').html(targetModel.get('date')); this.$currentPost.find('.date-display').text(targetModel.get('date'));
this.$currentPost.find('.date').val(targetModel.get('date')); this.$currentPost.find('.date').val(targetModel.get('date'));
var content = CourseInfoHelper.changeContentToPreview( content = HtmlUtils.HTML(CourseInfoHelper.changeContentToPreview(
targetModel, 'content', this.options['base_asset_url']); targetModel, 'content', this.options.base_asset_url
));
try { try {
// just in case the content causes an error (embedded js errors) // just in case the content causes an error (embedded js errors)
this.$currentPost.find('.update-contents').html(content); HtmlUtils.setHtml(this.$currentPost.find('.update-contents'), content);
this.$currentPost.find('.new-update-content').val(content); this.$currentPost.find('.new-update-content').val(content);
} catch (e) { } catch (e) {
// ignore but handle rest of page // ignore but handle rest of page
......
...@@ -45,7 +45,7 @@ from openedx.core.djangolib.js_utils import ( ...@@ -45,7 +45,7 @@ from openedx.core.djangolib.js_utils import (
<h3 class="sr">${_('Page Actions')}</h3> <h3 class="sr">${_('Page Actions')}</h3>
<ul> <ul>
<li class="nav-item"> <li class="nav-item">
<a href="#" class=" button new-button new-update-button"><span class="icon fa fa-plus" aria-hidden="true"></span> ${_('New Update')}</a> <a href="#" class=" button new-button new-update-button" disabled><span class="icon fa fa-plus" aria-hidden="true"></span> ${_('New Update')}</a>
</li> </li>
</ul> </ul>
</nav> </nav>
......
...@@ -37,6 +37,14 @@ class CourseUpdatesPage(CoursePage): ...@@ -37,6 +37,14 @@ class CourseUpdatesPage(CoursePage):
""" """
Clicks the new-update button. Clicks the new-update button.
""" """
def is_update_button_enabled():
"""
Checks if the New Update button is enabled
"""
return self.q(css='.new-update-button').attrs('disabled')[0] is None
self.wait_for(promise_check_func=is_update_button_enabled,
description='Waiting for the New update button to be enabled.')
click_css(self, '.new-update-button', require_notification=False) click_css(self, '.new-update-button', require_notification=False)
self.wait_for_element_visibility('.CodeMirror', 'Waiting for .CodeMirror') self.wait_for_element_visibility('.CodeMirror', 'Waiting for .CodeMirror')
......
""" """
Acceptance Tests for Course Information Acceptance Tests for Course Information
""" """
from flaky import flaky
from common.test.acceptance.pages.studio.course_info import CourseUpdatesPage from common.test.acceptance.pages.studio.course_info import CourseUpdatesPage
from common.test.acceptance.tests.studio.base_studio_test import StudioCourseTest from common.test.acceptance.tests.studio.base_studio_test import StudioCourseTest
...@@ -79,7 +77,6 @@ class UsersCanAddUpdatesTest(StudioCourseTest): ...@@ -79,7 +77,6 @@ class UsersCanAddUpdatesTest(StudioCourseTest):
self.assertFalse(self.course_updates_page.is_first_update_message('Hello')) self.assertFalse(self.course_updates_page.is_first_update_message('Hello'))
self.assertTrue(self.course_updates_page.is_first_update_message('Goodbye')) self.assertTrue(self.course_updates_page.is_first_update_message('Goodbye'))
@flaky # TNL-5582
def test_delete_course_update(self): def test_delete_course_update(self):
""" """
Scenario: Users can delete updates Scenario: Users can delete updates
...@@ -109,7 +106,6 @@ class UsersCanAddUpdatesTest(StudioCourseTest): ...@@ -109,7 +106,6 @@ class UsersCanAddUpdatesTest(StudioCourseTest):
self.course_updates_page.click_new_update_save_button() self.course_updates_page.click_new_update_save_button()
self.assertTrue(self.course_updates_page.is_first_update_date('June 1, 2013')) self.assertTrue(self.course_updates_page.is_first_update_date('June 1, 2013'))
@flaky # TNL-5775
def test_outside_tag_preserved(self): def test_outside_tag_preserved(self):
""" """
Scenario: Text outside of tags is preserved Scenario: Text outside of tags is preserved
...@@ -124,7 +120,6 @@ class UsersCanAddUpdatesTest(StudioCourseTest): ...@@ -124,7 +120,6 @@ class UsersCanAddUpdatesTest(StudioCourseTest):
self.course_updates_page.visit() self.course_updates_page.visit()
self.assertTrue(self.course_updates_page.is_first_update_message('before <strong>middle</strong> after')) self.assertTrue(self.course_updates_page.is_first_update_message('before <strong>middle</strong> after'))
@flaky # TNL-5773
def test_asset_change_in_updates(self): def test_asset_change_in_updates(self):
""" """
Scenario: Static links are rewritten when previewing a course update Scenario: Static links are rewritten when previewing a course update
......
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