diff --git a/CHANGELOG.rst b/CHANGELOG.rst index 8ad10f8eca..7f736932fd 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -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 the top. Include a label indicating the component affected. +Studio: Add edit button to leaf xblocks on the container page. STUD-1306. + Blades: Add LTI context_id parameter. BLD-584. Blades: Update LTI resource_link_id parameter. BLD-768. diff --git a/cms/djangoapps/contentstore/features/component_settings_editor_helpers.py b/cms/djangoapps/contentstore/features/component_settings_editor_helpers.py index 60632f77a7..7431eb3ed9 100644 --- a/cms/djangoapps/contentstore/features/component_settings_editor_helpers.py +++ b/cms/djangoapps/contentstore/features/component_settings_editor_helpers.py @@ -107,7 +107,7 @@ def click_component_from_menu(category, component_type, is_advanced): def edit_component_and_select_settings(): world.wait_for(lambda _driver: world.css_visible('a.edit-button')) world.css_click('a.edit-button') - world.css_click('#settings-mode a') + world.css_click('.settings-button') @world.absorb @@ -174,7 +174,7 @@ def verify_all_setting_entries(expected_entries): @world.absorb def save_component(step): - world.css_click("a.save-button") + world.css_click("a.action-save") world.wait_for_ajax_complete() @@ -189,7 +189,7 @@ def save_component_and_reopen(step): @world.absorb def cancel_component(step): - world.css_click("a.cancel-button") + world.css_click("a.action-cancel") # We have a known issue that modifications are still shown within the edit window after cancel (though) # they are not persisted. Refresh the browser to make sure the changes were not persisted. reload_the_page(step) diff --git a/cms/djangoapps/contentstore/features/pages.py b/cms/djangoapps/contentstore/features/pages.py index e86177282d..2306dfb768 100644 --- a/cms/djangoapps/contentstore/features/pages.py +++ b/cms/djangoapps/contentstore/features/pages.py @@ -44,13 +44,13 @@ def click_edit_or_delete(step, edit_or_delete): @step(u'I change the name to "([^"]*)"$') def change_name(step, new_name): - settings_css = '#settings-mode a' + settings_css = '.settings-button' world.css_click(settings_css) input_css = 'input.setting-input' world.css_fill(input_css, new_name) if world.is_firefox(): world.trigger_event(input_css) - save_button = 'a.save-button' + save_button = 'a.action-save' world.css_click(save_button) diff --git a/cms/djangoapps/contentstore/features/transcripts.py b/cms/djangoapps/contentstore/features/transcripts.py index e198ee3f32..636b5dd83a 100644 --- a/cms/djangoapps/contentstore/features/transcripts.py +++ b/cms/djangoapps/contentstore/features/transcripts.py @@ -209,23 +209,31 @@ def check_text_in_the_captions(_step, text): @step('I see value "([^"]*)" in the field "([^"]*)"$') def check_transcripts_field(_step, values, field_name): - world.click_link_by_text('Advanced') + editor_tabs = world.browser.find_by_css('.editor-tabs a') + basic_tab = editor_tabs[0] + advanced_tab = editor_tabs[1] + advanced_tab.click() 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('|')] assert any(values_list) - world.click_link_by_text('Basic') + basic_tab.click() @step('I save changes$') def save_changes(_step): - save_css = 'a.save-button' + save_css = 'a.action-save' world.css_click(save_css) world.wait_for_ajax_complete() @step('I open tab "([^"]*)"$') def open_tab(_step, tab_name): - world.click_link_by_text(tab_name.strip()) + editor_tabs = world.browser.find_by_css('.editor-tabs a') + expected_tab_text = tab_name.strip().upper() + matching_tabs = [tab for tab in editor_tabs if tab.text == expected_tab_text] + assert len(matching_tabs) == 1 + tab = matching_tabs[0] + tab.click() world.wait_for_ajax_complete() diff --git a/cms/djangoapps/contentstore/features/video-editor.py b/cms/djangoapps/contentstore/features/video-editor.py index a7974f020f..abff4bd74a 100644 --- a/cms/djangoapps/contentstore/features/video-editor.py +++ b/cms/djangoapps/contentstore/features/video-editor.py @@ -113,10 +113,10 @@ def set_show_captions(step, setting): world.browser.cookies.delete('hide_captions') world.css_click('a.edit-button') - world.wait_for(lambda _driver: world.css_visible('a.save-button')) - world.click_link_by_text('Advanced') + world.wait_for(lambda _driver: world.css_visible('a.action-save')) + world.click_link_by_text('ADVANCED') world.browser.select('Transcript Display', setting) - world.css_click('a.save-button') + world.css_click('a.action-save') @step('when I view the video it (.*) show the captions$') @@ -161,7 +161,7 @@ def correct_video_settings(_step): @step('my video display name change is persisted on save$') def video_name_persisted(step): - world.css_click('a.save-button') + world.css_click('a.action-save') reload_the_page(step) world.wait_for_xmodule() world.edit_component() diff --git a/cms/djangoapps/contentstore/views/component.py b/cms/djangoapps/contentstore/views/component.py index e2152d9872..3161575309 100644 --- a/cms/djangoapps/contentstore/views/component.py +++ b/cms/djangoapps/contentstore/views/component.py @@ -273,6 +273,7 @@ def unit_handler(request, tag=None, package_id=None, branch=None, version_guid=N 'context_course': course, 'unit': item, 'unit_locator': locator, + 'xblocks': [xblock for xblock in xblocks], 'locators': locators, 'component_templates': component_templates, 'draft_preview_link': preview_lms_link, @@ -317,14 +318,17 @@ def container_handler(request, tag=None, package_id=None, branch=None, version_g while parent and parent.category != 'sequential': ancestor_xblocks.append(parent) parent = get_parent_xblock(parent) - ancestor_xblocks.reverse() + unit = None if not ancestor_xblocks else ancestor_xblocks[0] + unit_publish_state = None if not unit else compute_publish_state(unit) + return render_to_response('container.html', { 'context_course': course, 'xblock': xblock, 'xblock_locator': locator, - 'unit': None if not ancestor_xblocks else ancestor_xblocks[0], + 'unit': unit, + 'unit_publish_state': unit_publish_state, 'ancestor_xblocks': ancestor_xblocks, }) else: diff --git a/cms/djangoapps/contentstore/views/item.py b/cms/djangoapps/contentstore/views/item.py index 344c6d5c57..f27df9c1b5 100644 --- a/cms/djangoapps/contentstore/views/item.py +++ b/cms/djangoapps/contentstore/views/item.py @@ -34,6 +34,7 @@ from ..utils import get_modulestore from .access import has_course_access from .helpers import _xmodule_recurse +from contentstore.utils import compute_publish_state, PublishState from contentstore.views.preview import get_preview_fragment from edxmako.shortcuts import render_to_string from models.settings.course_grading import CourseGradingModel @@ -224,11 +225,12 @@ def xblock_view_handler(request, package_id, view_name, tag=None, branch=None, v }) elif view_name in ('student_view', 'container_preview'): is_container_view = (view_name == 'container_preview') + component_publish_state = compute_publish_state(component) + is_read_only_view = component_publish_state == PublishState.public # Only show the new style HTML for the container view, i.e. for non-verticals # Note: this special case logic can be removed once the unit page is replaced # with the new container view. - is_read_only_view = is_container_view context = { 'runtime_type': 'studio', 'container_view': is_container_view, diff --git a/cms/djangoapps/contentstore/views/preview.py b/cms/djangoapps/contentstore/views/preview.py index b3e4f0562e..17c1548299 100644 --- a/cms/djangoapps/contentstore/views/preview.py +++ b/cms/djangoapps/contentstore/views/preview.py @@ -1,7 +1,6 @@ from __future__ import absolute_import import logging -import hashlib from functools import partial from django.conf import settings @@ -170,7 +169,7 @@ def _studio_wrap_xblock(xblock, view, frag, context, display_name_only=False): """ # Only add the Studio wrapper when on the container page. The unit page will remain as is for now. if context.get('container_view', None) and view == 'student_view': - locator = loc_mapper().translate_location(xblock.course_id, xblock.location) + locator = loc_mapper().translate_location(xblock.course_id, xblock.location, published=False) template_context = { 'xblock_context': context, 'xblock': xblock, diff --git a/cms/djangoapps/contentstore/views/tests/test_container.py b/cms/djangoapps/contentstore/views/tests/test_container.py index 0752ca6141..fefc19ea21 100644 --- a/cms/djangoapps/contentstore/views/tests/test_container.py +++ b/cms/djangoapps/contentstore/views/tests/test_container.py @@ -3,6 +3,7 @@ Unit tests for the container view. """ from contentstore.tests.utils import CourseTestCase +from contentstore.utils import compute_publish_state, PublishState from contentstore.views.helpers import xblock_studio_url from xmodule.modulestore.tests.factories import ItemFactory @@ -26,13 +27,19 @@ class ContainerViewTestCase(CourseTestCase): category="video", display_name="My Video") def test_container_html(self): + branch_name = "MITx.999.Robot_Super_Course/branch/draft/block" self._test_html_content( self.child_vertical, - expected_section_tag='
', + branch_name=branch_name, + expected_section_tag=( + '