Commit b4f82b38 by polesye

BLD-438: Fix clear and download buttons.

parent beda1f8b
...@@ -5,6 +5,8 @@ These are notable changes in edx-platform. This is a rolling list of changes, ...@@ -5,6 +5,8 @@ These are notable changes in edx-platform. This is a rolling list of changes,
in roughly chronological order, most recent first. Add your entries at or near in roughly chronological order, most recent first. Add your entries at or near
the top. Include a label indicating the component affected. the top. Include a label indicating the component affected.
Blades: Video Transcripts: Fix clear and download buttons. BLD-438.
Common: Switch over from MITX_FEATURES to just FEATURES. To override items in Common: Switch over from MITX_FEATURES to just FEATURES. To override items in
the FEATURES dict, the environment variable you must set to do so is also the FEATURES dict, the environment variable you must set to do so is also
now called FEATURES instead of MITX_FEATURES. now called FEATURES instead of MITX_FEATURES.
......
...@@ -653,3 +653,25 @@ Feature: Video Component Editor ...@@ -653,3 +653,25 @@ Feature: Video Component Editor
Then when I view the video it does show the captions Then when I view the video it does show the captions
And I see "LILA FISHER: Hi, welcome to Edx." text in the captions And I see "LILA FISHER: Hi, welcome to Edx." text in the captions
#35
Scenario: After reverting Transcripts field in the Advanced tab "not found" message should be visible
Given I have created a Video component
And I edit the component
And I enter a "t_not_exist.mp4" source to field number 1
Then I see status message "not found"
And I upload the transcripts file "chinese_transcripts.srt"
Then I see status message "uploaded_successfully"
And I save changes
Then I see "好 各位同学" text in the captions
And I edit the component
And I open tab "Advanced"
And I revert the transcript field"HTML5 Transcript"
And I save changes
Then when I view the video it does not show the captions
And I edit the component
Then I see status message "not found"
...@@ -9,7 +9,7 @@ from django.conf import settings ...@@ -9,7 +9,7 @@ from django.conf import settings
from xmodule.contentstore.content import StaticContent from xmodule.contentstore.content import StaticContent
from xmodule.contentstore.django import contentstore from xmodule.contentstore.django import contentstore
from xmodule.exceptions import NotFoundError from xmodule.exceptions import NotFoundError
from splinter.request_handler.request_handler import RequestHandler
TEST_ROOT = settings.COMMON_TEST_DATA_ROOT TEST_ROOT = settings.COMMON_TEST_DATA_ROOT
...@@ -49,6 +49,13 @@ TRANSCRIPTS_BUTTONS = { ...@@ -49,6 +49,13 @@ TRANSCRIPTS_BUTTONS = {
} }
def _clear_field(index):
world.css_fill(SELECTORS['url_inputs'], '', index)
# In some reason chromeDriver doesn't trigger 'input' event after filling
# field by an empty value. That's why we trigger it manually via jQuery.
world.trigger_event(SELECTORS['url_inputs'], event='input', index=index)
@step('I clear fields$') @step('I clear fields$')
def clear_fields(_step): def clear_fields(_step):
js_str = ''' js_str = '''
...@@ -60,16 +67,18 @@ def clear_fields(_step): ...@@ -60,16 +67,18 @@ def clear_fields(_step):
for index in range(1, 4): for index in range(1, 4):
js = js_str.format(selector=SELECTORS['url_inputs'], index=index - 1) js = js_str.format(selector=SELECTORS['url_inputs'], index=index - 1)
world.browser.execute_script(js) world.browser.execute_script(js)
_step.given('I clear field number {0}'.format(index)) _clear_field(index)
world.wait(DELAY)
world.wait_for_ajax_complete()
@step('I clear field number (.+)$') @step('I clear field number (.+)$')
def clear_field(_step, index): def clear_field(_step, index):
index = int(index) - 1 index = int(index) - 1
world.css_fill(SELECTORS['url_inputs'], '', index) _clear_field(index)
# In some reason chromeDriver doesn't trigger 'input' event after filling world.wait(DELAY)
# field by an empty value. That's why we trigger it manually via jQuery. world.wait_for_ajax_complete()
world.trigger_event(SELECTORS['url_inputs'], event='input', index=index)
@step('I expect (.+) inputs are disabled$') @step('I expect (.+) inputs are disabled$')
...@@ -91,40 +100,32 @@ def inputs_are_enabled(_step): ...@@ -91,40 +100,32 @@ def inputs_are_enabled(_step):
@step('I do not see error message$') @step('I do not see error message$')
def i_do_not_see_error_message(_step): def i_do_not_see_error_message(_step):
world.wait(DELAY)
assert not world.css_visible(SELECTORS['error_bar']) assert not world.css_visible(SELECTORS['error_bar'])
@step('I see error message "([^"]*)"$') @step('I see error message "([^"]*)"$')
def i_see_error_message(_step, error): def i_see_error_message(_step, error):
world.wait(DELAY)
assert world.css_has_text(SELECTORS['error_bar'], ERROR_MESSAGES[error.strip()]) assert world.css_has_text(SELECTORS['error_bar'], ERROR_MESSAGES[error.strip()])
@step('I do not see status message$') @step('I do not see status message$')
def i_do_not_see_status_message(_step): def i_do_not_see_status_message(_step):
world.wait(DELAY)
world.wait_for_ajax_complete()
assert not world.css_visible(SELECTORS['status_bar']) assert not world.css_visible(SELECTORS['status_bar'])
@step('I see status message "([^"]*)"$') @step('I see status message "([^"]*)"$')
def i_see_status_message(_step, status): def i_see_status_message(_step, status):
world.wait(DELAY)
world.wait_for_ajax_complete()
assert not world.css_visible(SELECTORS['error_bar']) assert not world.css_visible(SELECTORS['error_bar'])
assert world.css_has_text(SELECTORS['status_bar'], STATUSES[status.strip()]) assert world.css_has_text(SELECTORS['status_bar'], STATUSES[status.strip()])
DOWNLOAD_BUTTON = TRANSCRIPTS_BUTTONS["download_to_edit"][0]
if world.is_css_present(DOWNLOAD_BUTTON, wait_time=1) \
and not world.css_find(DOWNLOAD_BUTTON)[0].has_class('is-disabled'):
assert _transcripts_are_downloaded()
@step('I (.*)see button "([^"]*)"$') @step('I (.*)see button "([^"]*)"$')
def i_see_button(_step, not_see, button_type): def i_see_button(_step, not_see, button_type):
world.wait(DELAY)
world.wait_for_ajax_complete()
button = button_type.strip() button = button_type.strip()
if not_see.strip(): if not_see.strip():
...@@ -135,9 +136,6 @@ def i_see_button(_step, not_see, button_type): ...@@ -135,9 +136,6 @@ def i_see_button(_step, not_see, button_type):
@step('I (.*)see (.*)button "([^"]*)" number (\d+)$') @step('I (.*)see (.*)button "([^"]*)" number (\d+)$')
def i_see_button_with_custom_text(_step, not_see, button_type, custom_text, index): def i_see_button_with_custom_text(_step, not_see, button_type, custom_text, index):
world.wait(DELAY)
world.wait_for_ajax_complete()
button = button_type.strip() button = button_type.strip()
custom_text = custom_text.strip() custom_text = custom_text.strip()
index = int(index.strip()) - 1 index = int(index.strip()) - 1
...@@ -150,22 +148,18 @@ def i_see_button_with_custom_text(_step, not_see, button_type, custom_text, inde ...@@ -150,22 +148,18 @@ def i_see_button_with_custom_text(_step, not_see, button_type, custom_text, inde
@step('I click transcript button "([^"]*)"$') @step('I click transcript button "([^"]*)"$')
def click_button_transcripts_variant(_step, button_type): def click_button_transcripts_variant(_step, button_type):
world.wait(DELAY)
world.wait_for_ajax_complete()
button = button_type.strip() button = button_type.strip()
world.css_click(TRANSCRIPTS_BUTTONS[button][0]) world.css_click(TRANSCRIPTS_BUTTONS[button][0])
world.wait_for_ajax_complete()
@step('I click transcript button "([^"]*)" number (\d+)$') @step('I click transcript button "([^"]*)" number (\d+)$')
def click_button_index(_step, button_type, index): def click_button_index(_step, button_type, index):
world.wait(DELAY)
world.wait_for_ajax_complete()
button = button_type.strip() button = button_type.strip()
index = int(index.strip()) - 1 index = int(index.strip()) - 1
world.css_click(TRANSCRIPTS_BUTTONS[button][0], index) world.css_click(TRANSCRIPTS_BUTTONS[button][0], index)
world.wait_for_ajax_complete()
@step('I remove "([^"]+)" transcripts id from store') @step('I remove "([^"]+)" transcripts id from store')
...@@ -187,9 +181,6 @@ def remove_transcripts_from_store(_step, subs_id): ...@@ -187,9 +181,6 @@ def remove_transcripts_from_store(_step, subs_id):
@step('I enter a "([^"]+)" source to field number (\d+)$') @step('I enter a "([^"]+)" source to field number (\d+)$')
def i_enter_a_source(_step, link, index): def i_enter_a_source(_step, link, index):
world.wait(DELAY)
world.wait_for_ajax_complete()
index = int(index) - 1 index = int(index) - 1
if index is not 0 and not world.css_visible(SELECTORS['collapse_bar']): if index is not 0 and not world.css_visible(SELECTORS['collapse_bar']):
...@@ -198,6 +189,8 @@ def i_enter_a_source(_step, link, index): ...@@ -198,6 +189,8 @@ def i_enter_a_source(_step, link, index):
assert world.css_visible(SELECTORS['collapse_bar']) assert world.css_visible(SELECTORS['collapse_bar'])
world.css_fill(SELECTORS['url_inputs'], link, index) world.css_fill(SELECTORS['url_inputs'], link, index)
world.wait(DELAY)
world.wait_for_ajax_complete()
@step('I upload the transcripts file "([^"]*)"$') @step('I upload the transcripts file "([^"]*)"$')
...@@ -205,6 +198,7 @@ def upload_file(_step, file_name): ...@@ -205,6 +198,7 @@ def upload_file(_step, file_name):
path = os.path.join(TEST_ROOT, 'uploads/', file_name.strip()) path = os.path.join(TEST_ROOT, 'uploads/', file_name.strip())
world.browser.execute_script("$('form.file-chooser').show()") world.browser.execute_script("$('form.file-chooser').show()")
world.browser.attach_file('file', os.path.abspath(path)) world.browser.attach_file('file', os.path.abspath(path))
world.wait_for_ajax_complete()
@step('I see "([^"]*)" text in the captions') @step('I see "([^"]*)" text in the captions')
...@@ -214,9 +208,6 @@ def check_text_in_the_captions(_step, text): ...@@ -214,9 +208,6 @@ def check_text_in_the_captions(_step, text):
@step('I see value "([^"]*)" in the field "([^"]*)"$') @step('I see value "([^"]*)" in the field "([^"]*)"$')
def check_transcripts_field(_step, values, field_name): def check_transcripts_field(_step, values, field_name):
world.wait(DELAY)
world.wait_for_ajax_complete()
world.click_link_by_text('Advanced') world.click_link_by_text('Advanced')
field_id = '#' + world.browser.find_by_xpath('//label[text()="%s"]' % field_name.strip())[0]['for'] field_id = '#' + world.browser.find_by_xpath('//label[text()="%s"]' % field_name.strip())[0]['for']
values_list = [i.strip() == world.css_value(field_id) for i in values.split('|')] values_list = [i.strip() == world.css_value(field_id) for i in values.split('|')]
...@@ -226,22 +217,34 @@ def check_transcripts_field(_step, values, field_name): ...@@ -226,22 +217,34 @@ def check_transcripts_field(_step, values, field_name):
@step('I save changes$') @step('I save changes$')
def save_changes(_step): def save_changes(_step):
world.wait(DELAY)
world.wait_for_ajax_complete()
save_css = 'a.save-button' save_css = 'a.save-button'
world.css_click(save_css) world.css_click(save_css)
world.wait_for_ajax_complete()
@step('I open tab "([^"]*)"$') @step('I open tab "([^"]*)"$')
def open_tab(_step, tab_name): def open_tab(_step, tab_name):
world.click_link_by_text(tab_name.strip()) world.click_link_by_text(tab_name.strip())
world.wait_for_ajax_complete()
@step('I set value "([^"]*)" to the field "([^"]*)"$') @step('I set value "([^"]*)" to the field "([^"]*)"$')
def set_value_transcripts_field(_step, value, field_name): def set_value_transcripts_field(_step, value, field_name):
world.wait(DELAY)
world.wait_for_ajax_complete()
field_id = '#' + world.browser.find_by_xpath('//label[text()="%s"]' % field_name.strip())[0]['for'] field_id = '#' + world.browser.find_by_xpath('//label[text()="%s"]' % field_name.strip())[0]['for']
world.css_fill(field_id, value.strip()) world.css_fill(field_id, value.strip())
world.wait_for_ajax_complete()
@step('I revert the transcript field "([^"]*)"$')
def revert_transcripts_field(_step, field_name):
world.revert_setting_entry(field_name)
def _transcripts_are_downloaded():
world.wait_for_ajax_complete()
request = RequestHandler()
DOWNLOAD_BUTTON = world.css_find(TRANSCRIPTS_BUTTONS["download_to_edit"][0]).first
url = DOWNLOAD_BUTTON['href']
request.connect(url)
return request.status_code.is_success()
...@@ -196,6 +196,7 @@ def remove_subs_from_store(subs_id, item): ...@@ -196,6 +196,7 @@ def remove_subs_from_store(subs_id, item):
try: try:
content = contentstore().find(content_location) content = contentstore().find(content_location)
contentstore().delete(content.get_id()) contentstore().delete(content.get_id())
del_cached_content(content.location)
log.info("Removed subs %s from store", subs_id) log.info("Removed subs %s from store", subs_id)
except NotFoundError: except NotFoundError:
pass pass
...@@ -310,7 +311,9 @@ def manage_video_subtitles_save(old_item, new_item): ...@@ -310,7 +311,9 @@ def manage_video_subtitles_save(old_item, new_item):
Video player item has some video fields: HTML5 ones and Youtube one. Video player item has some video fields: HTML5 ones and Youtube one.
1. If value of `sub` field of `new_item` is different from values of video fields of `new_item`, If value of `sub` field of `new_item` is cleared, transcripts should be removed.
If value of `sub` field of `new_item` is different from values of video fields of `new_item`,
and `new_item.sub` file is present, then code in this function creates copies of and `new_item.sub` file is present, then code in this function creates copies of
`new_item.sub` file with new names. That names are equal to values of video fields of `new_item` `new_item.sub` file with new names. That names are equal to values of video fields of `new_item`
After that `sub` field of `new_item` is changed to one of values of video fields. After that `sub` field of `new_item` is changed to one of values of video fields.
...@@ -328,6 +331,9 @@ def manage_video_subtitles_save(old_item, new_item): ...@@ -328,6 +331,9 @@ def manage_video_subtitles_save(old_item, new_item):
for video_id in possible_video_id_list: for video_id in possible_video_id_list:
if not video_id: if not video_id:
continue continue
if not sub_name:
remove_subs_from_store(video_id, new_item)
continue
# copy_or_rename_transcript changes item.sub of module # copy_or_rename_transcript changes item.sub of module
try: try:
# updates item.sub with `video_id`, if it is successful. # updates item.sub with `video_id`, if it is successful.
......
...@@ -90,7 +90,17 @@ function($, Backbone, _, Utils, MetadataView, MetadataCollection) { ...@@ -90,7 +90,17 @@ function($, Backbone, _, Utils, MetadataView, MetadataCollection) {
var isSubsModified = (function (values) { var isSubsModified = (function (values) {
var isSubsChanged = subs.hasChanged("value"); var isSubsChanged = subs.hasChanged("value");
return Boolean(isSubsChanged && _.isString(values.sub)); return Boolean(
isSubsChanged &&
(
// If the user changes the field, `values.sub` contains
// string value;
// If the user clicks `clear` button, the field contains
// null value.
// Otherwise, undefined.
_.isString(values.sub) || _.isNull(subs.getValue())
)
);
}(modifiedValues)); }(modifiedValues));
// When we change value of `sub` field in the `Advanced`, // When we change value of `sub` field in the `Advanced`,
......
...@@ -10,7 +10,7 @@ ...@@ -10,7 +10,7 @@
<button class="action setting-upload" type="button" name="setting-upload" value="<%= gettext("Upload New Timed Transcript") %>" data-tooltip="<%= gettext("Upload New Timed Transcript") %>"> <button class="action setting-upload" type="button" name="setting-upload" value="<%= gettext("Upload New Timed Transcript") %>" data-tooltip="<%= gettext("Upload New Timed Transcript") %>">
<span><%= gettext("Upload New Timed Transcript") %></span> <span><%= gettext("Upload New Timed Transcript") %></span>
</button> </button>
<a class="action setting-download" href="/transcripts/download?locator=<%= component_locator %>" data-tooltip="<%= gettext("Download to Edit") %>"> <a class="action setting-download" href="/transcripts/download?locator=<%= component_locator %>&subs_id=<%= subs_id %>" data-tooltip="<%= gettext("Download to Edit") %>">
<span><%= gettext("Download to Edit") %></span> <span><%= gettext("Download to Edit") %></span>
</a> </a>
</div> </div>
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