Commit 7b8b4abb by Braden MacDonald

Revert "OC-1320 DnDv2 - Allow to set automatic alignment of dragged items in drop zones"

parent 02529c95
...@@ -11,7 +11,6 @@ The editor is fully guided. Features include: ...@@ -11,7 +11,6 @@ The editor is fully guided. Features include:
* custom zone labels * custom zone labels
* ability to show or hide zone borders * ability to show or hide zone borders
* custom text and background colors for items * custom text and background colors for items
* optional auto-alignment for items (left, right, center)
* image items * image items
* items prompting for additional (numerical) input after being dropped * items prompting for additional (numerical) input after being dropped
* decoy items that don't have a zone * decoy items that don't have a zone
...@@ -103,7 +102,7 @@ above the background image, the introductory feedback (shown ...@@ -103,7 +102,7 @@ above the background image, the introductory feedback (shown
initially), and the final feedback (shown after the learner initially), and the final feedback (shown after the learner
successfully completes the drag and drop problem). successfully completes the drag and drop problem).
![Drop zone edit](https://raw.githubusercontent.com/edx-solutions/xblock-drag-and-drop-v2/ebd0b52d971bbf93b9c3873f310bd72d336d865b/doc/img/edit-view-zones.png) ![Drop zone edit](https://raw.githubusercontent.com/edx-solutions/xblock-drag-and-drop-v2/c955a38dc3a1aaf609c586d293ce19b282e11ffd/doc/img/edit-view-zones.png)
In the next step, you set the URL and description for the background In the next step, you set the URL and description for the background
image and define the properties of the drop zones. For each zone you image and define the properties of the drop zones. For each zone you
...@@ -115,16 +114,6 @@ whether or not to display borders outlining the zones. It is possible ...@@ -115,16 +114,6 @@ whether or not to display borders outlining the zones. It is possible
to define an arbitrary number of drop zones as long as their labels to define an arbitrary number of drop zones as long as their labels
are unique. are unique.
Additionally, you can specify the alignment for items once they are dropped in
the zone. No alignment is the default, and causes items to stay where the
learner drops them. Left alignment causes dropped items to be placed from left
to right across the zone. Right alignment causes the items to be placed from
right to left across the zone. Center alignment places items from top to bottom
along the center of the zone. If left, right, or center alignment is chosen,
items dropped in a zone will not overlap, but if the zone is not made large
enough for all its items, they will overflow the bottom of the zone, and
potentially, overlap the zones below.
![Drag item edit](https://raw.githubusercontent.com/edx-solutions/xblock-drag-and-drop-v2/c955a38dc3a1aaf609c586d293ce19b282e11ffd/doc/img/edit-view-items.png) ![Drag item edit](https://raw.githubusercontent.com/edx-solutions/xblock-drag-and-drop-v2/c955a38dc3a1aaf609c586d293ce19b282e11ffd/doc/img/edit-view-items.png)
In the final step, you define the background and text color for drag In the final step, you define the background and text color for drag
......
doc/img/edit-view-zones.png

77.3 KB | W: | H:

doc/img/edit-view-zones.png

52.5 KB | W: | H:

doc/img/edit-view-zones.png
doc/img/edit-view-zones.png
doc/img/edit-view-zones.png
doc/img/edit-view-zones.png
  • 2-up
  • Swipe
  • Onion skin
...@@ -142,33 +142,6 @@ ...@@ -142,33 +142,6 @@
transform: translate(-50%, -50%); /* These blocks are to be centered on their absolute x,y position */ transform: translate(-50%, -50%); /* These blocks are to be centered on their absolute x,y position */
} }
/* Placed options in an aligned zone */
.xblock--drag-and-drop .zone .item-wrapper {
width: 100%;
position: relative;
}
.xblock--drag-and-drop .zone .item-align .option {
transform: none;
position: relative;
vertical-align: top;
margin-right: 2px;
margin-bottom: 2px;
}
.xblock--drag-and-drop .zone .item-align-left {
text-align: left;
}
.xblock--drag-and-drop .zone .item-align-right {
text-align: right;
}
.xblock--drag-and-drop .zone .item-align-center {
text-align: center;
}
.xblock--drag-and-drop .zone .item-align-center .option {
display: block;
margin-left: auto;
margin-right: auto;
}
/* Focused option */ /* Focused option */
.xblock--drag-and-drop .drag-container .item-bank .option:focus, .xblock--drag-and-drop .drag-container .item-bank .option:focus,
.xblock--drag-and-drop .drag-container .item-bank .option:hover, .xblock--drag-and-drop .drag-container .item-bank .option:hover,
......
...@@ -144,7 +144,7 @@ ...@@ -144,7 +144,7 @@
here we make sure that both input fields get the same value for line-height */ here we make sure that both input fields get the same value for line-height */
} }
.xblock--drag-and-drop--editor .zones-form .zone-row .alignment { .xblock--drag-and-drop--editor .zones-form .zone-row .layout {
margin-bottom: 15px; margin-bottom: 15px;
} }
...@@ -160,7 +160,6 @@ ...@@ -160,7 +160,6 @@
height: 128px; height: 128px;
} }
.xblock--drag-and-drop--editor .zones-form .zones-form-help,
.xblock--drag-and-drop--editor .target-image-form .target-image-form-help, .xblock--drag-and-drop--editor .target-image-form .target-image-form-help,
.xblock--drag-and-drop--editor .item-styles-form .item-styles-form-help { .xblock--drag-and-drop--editor .item-styles-form .item-styles-form-help {
margin-top: 5px; margin-top: 5px;
......
...@@ -79,15 +79,8 @@ function DragNDropTemplates(url_name) { ...@@ -79,15 +79,8 @@ function DragNDropTemplates(url_name) {
style['outline-color'] = item.color; style['outline-color'] = item.color;
} }
if (item.is_placed) { if (item.is_placed) {
if (item.zone_align === 'none') { style.left = item.x_percent + "%";
style.left = item.x_percent + "%"; style.top = item.y_percent + "%";
style.top = item.y_percent + "%";
} else {
// Allow for the input + button width for aligned items
if (item.input) {
style.marginRight = '190px';
}
}
if (item.widthPercent) { if (item.widthPercent) {
style.width = item.widthPercent + "%"; style.width = item.widthPercent + "%";
style.maxWidth = item.widthPercent + "%"; // default maxWidth is ~33% style.maxWidth = item.widthPercent + "%"; // default maxWidth is ~33%
...@@ -150,16 +143,6 @@ function DragNDropTemplates(url_name) { ...@@ -150,16 +143,6 @@ function DragNDropTemplates(url_name) {
var zoneTemplate = function(zone, ctx) { var zoneTemplate = function(zone, ctx) {
var className = ctx.display_zone_labels ? 'zone-name' : 'zone-name sr'; var className = ctx.display_zone_labels ? 'zone-name' : 'zone-name sr';
var selector = ctx.display_zone_borders ? 'div.zone.zone-with-borders' : 'div.zone'; var selector = ctx.display_zone_borders ? 'div.zone.zone-with-borders' : 'div.zone';
// If zone is aligned, mark its item alignment
// and render its placed items as children
var item_wrapper = 'div.item-wrapper';
var items_in_zone = [];
if (zone.align !== 'none') {
item_wrapper += '.item-align.item-align-' + zone.align;
var is_item_in_zone = function(i) { return i.is_placed && (i.zone === zone.title); };
items_in_zone = $.grep(ctx.items, is_item_in_zone);
}
return ( return (
h( h(
selector, selector,
...@@ -170,7 +153,6 @@ function DragNDropTemplates(url_name) { ...@@ -170,7 +153,6 @@ function DragNDropTemplates(url_name) {
'dropzone': 'move', 'dropzone': 'move',
'aria-dropeffect': 'move', 'aria-dropeffect': 'move',
'data-zone': zone.title, 'data-zone': zone.title,
'data-zonealign': zone.align,
'role': 'button', 'role': 'button',
}, },
style: { style: {
...@@ -180,8 +162,7 @@ function DragNDropTemplates(url_name) { ...@@ -180,8 +162,7 @@ function DragNDropTemplates(url_name) {
}, },
[ [
h('p', { className: className }, zone.title), h('p', { className: className }, zone.title),
h('p', { className: 'zone-description sr' }, zone.description), h('p', { className: 'zone-description sr' }, zone.description)
h(item_wrapper, renderCollection(itemTemplate, items_in_zone, ctx))
] ]
) )
); );
...@@ -241,13 +222,9 @@ function DragNDropTemplates(url_name) { ...@@ -241,13 +222,9 @@ function DragNDropTemplates(url_name) {
if (ctx.popup_html && !ctx.last_action_correct) { if (ctx.popup_html && !ctx.last_action_correct) {
popupSelector += '.popup-incorrect'; popupSelector += '.popup-incorrect';
} }
// Render only items_in_bank and items_placed_unaligned here;
// items placed in aligned zones will be rendered by zoneTemplate.
var is_item_placed = function(i) { return i.is_placed; }; var is_item_placed = function(i) { return i.is_placed; };
var items_placed = $.grep(ctx.items, is_item_placed); var items_placed = $.grep(ctx.items, is_item_placed);
var items_in_bank = $.grep(ctx.items, is_item_placed, true); var items_in_bank = $.grep(ctx.items, is_item_placed, true);
var is_item_placed_unaligned = function(i) { return i.zone_align === 'none'; };
var items_placed_unaligned = $.grep(items_placed, is_item_placed_unaligned);
return ( return (
h('section.themed-xblock.xblock--drag-and-drop', [ h('section.themed-xblock.xblock--drag-and-drop', [
problemTitle, problemTitle,
...@@ -284,7 +261,7 @@ function DragNDropTemplates(url_name) { ...@@ -284,7 +261,7 @@ function DragNDropTemplates(url_name) {
] ]
), ),
renderCollection(zoneTemplate, ctx.zones, ctx), renderCollection(zoneTemplate, ctx.zones, ctx),
renderCollection(itemTemplate, items_placed_unaligned, ctx) renderCollection(itemTemplate, items_placed, ctx),
] ]
), ),
]), ]),
...@@ -346,7 +323,6 @@ function DragAndDropBlock(runtime, element, configuration) { ...@@ -346,7 +323,6 @@ function DragAndDropBlock(runtime, element, configuration) {
state = stateResult[0]; // stateResult is an array of [data, statusText, jqXHR] state = stateResult[0]; // stateResult is an array of [data, statusText, jqXHR]
migrateConfiguration(bgImg.width); migrateConfiguration(bgImg.width);
migrateState(bgImg.width, bgImg.height); migrateState(bgImg.width, bgImg.height);
markItemZoneAlign();
bgImgNaturalWidth = bgImg.width; bgImgNaturalWidth = bgImg.width;
// Set up event handlers: // Set up event handlers:
...@@ -607,7 +583,6 @@ function DragAndDropBlock(runtime, element, configuration) { ...@@ -607,7 +583,6 @@ function DragAndDropBlock(runtime, element, configuration) {
$anchor = $zone; $anchor = $zone;
} }
var zone = $zone.data('zone'); var zone = $zone.data('zone');
var zone_align = $zone.data('zonealign');
var $target_img = $root.find('.target-img'); var $target_img = $root.find('.target-img');
// Calculate the position of the item to place relative to the image. // Calculate the position of the item to place relative to the image.
...@@ -618,7 +593,6 @@ function DragAndDropBlock(runtime, element, configuration) { ...@@ -618,7 +593,6 @@ function DragAndDropBlock(runtime, element, configuration) {
state.items[item_id] = { state.items[item_id] = {
zone: zone, zone: zone,
zone_align: zone_align,
x_percent: x_pos_percent, x_percent: x_pos_percent,
y_percent: y_pos_percent, y_percent: y_pos_percent,
submitting_location: true, submitting_location: true,
...@@ -893,7 +867,6 @@ function DragAndDropBlock(runtime, element, configuration) { ...@@ -893,7 +867,6 @@ function DragAndDropBlock(runtime, element, configuration) {
if (item_user_state) { if (item_user_state) {
itemProperties.is_placed = true; itemProperties.is_placed = true;
itemProperties.zone = item_user_state.zone; itemProperties.zone = item_user_state.zone;
itemProperties.zone_align = item_user_state.zone_align;
itemProperties.x_percent = item_user_state.x_percent; itemProperties.x_percent = item_user_state.x_percent;
itemProperties.y_percent = item_user_state.y_percent; itemProperties.y_percent = item_user_state.y_percent;
} }
...@@ -978,22 +951,5 @@ function DragAndDropBlock(runtime, element, configuration) { ...@@ -978,22 +951,5 @@ function DragAndDropBlock(runtime, element, configuration) {
}); });
}; };
/**
* markItemZoneAlign: Mark the items placed in an aligned zone with the zone
* alignment, so they can be properly placed inside the zone.
* We have do this in JS, not python, since zone configurations may change.
*/
var markItemZoneAlign = function() {
var zone_alignments = {};
configuration.zones.forEach(function(zone) {
if (!zone.align) zone.align = 'none';
zone_alignments[zone.title] = zone.align;
});
Object.keys(state.items).forEach(function(item_id) {
var item = state.items[item_id];
item.zone_align = zone_alignments[item.zone] || 'none';
});
};
init(); init();
} }
...@@ -14,12 +14,6 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -14,12 +14,6 @@ function DragAndDropEditBlock(runtime, element, params) {
} }
return Number(value).toFixed(Number(value) == parseInt(value) ? 0 : 1); return Number(value).toFixed(Number(value) == parseInt(value) ? 0 : 1);
}); });
Handlebars.registerHelper('ifeq', function(v1, v2, options) {
if (v1 === v2) {
return options.fn(this);
}
return options.inverse(this);
});
var $element = $(element); var $element = $(element);
...@@ -170,7 +164,7 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -170,7 +164,7 @@ function DragAndDropEditBlock(runtime, element, params) {
_fn.build.form.zone.add(); _fn.build.form.zone.add();
}) })
.on('click', '.remove-zone', _fn.build.form.zone.remove) .on('click', '.remove-zone', _fn.build.form.zone.remove)
.on('input', '.zone-row input, .zone-row select', _fn.build.form.zone.changedInputHandler) .on('input', '.zone-row input', _fn.build.form.zone.changedInputHandler)
.on('click', '.target-image-form button', function(e) { .on('click', '.target-image-form button', function(e) {
e.preventDefault(); e.preventDefault();
...@@ -243,7 +237,6 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -243,7 +237,6 @@ function DragAndDropEditBlock(runtime, element, params) {
height: oldZone.height || 100, height: oldZone.height || 100,
x: oldZone.x || 0, x: oldZone.x || 0,
y: oldZone.y || 0, y: oldZone.y || 0,
align: oldZone.align || ''
}; };
_fn.build.form.zone.zoneObjects.push(zoneObj); _fn.build.form.zone.zoneObjects.push(zoneObj);
...@@ -310,7 +303,6 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -310,7 +303,6 @@ function DragAndDropEditBlock(runtime, element, params) {
y_percent: (+zoneObj.y) / imgHeight * 100, y_percent: (+zoneObj.y) / imgHeight * 100,
width_percent: (+zoneObj.width) / imgWidth * 100, width_percent: (+zoneObj.width) / imgWidth * 100,
height_percent: (+zoneObj.height) / imgHeight * 100, height_percent: (+zoneObj.height) / imgHeight * 100,
align: zoneObj.align
}) })
); );
}); });
...@@ -344,8 +336,6 @@ function DragAndDropEditBlock(runtime, element, params) { ...@@ -344,8 +336,6 @@ function DragAndDropEditBlock(runtime, element, params) {
record.x = $changedInput.val(); record.x = $changedInput.val();
} else if ($changedInput.hasClass('y')) { } else if ($changedInput.hasClass('y')) {
record.y = $changedInput.val(); record.y = $changedInput.val();
} else if ($changedInput.hasClass('align-select')) {
record.align = $changedInput.val();
} }
_fn.build.form.zone.renderZonesPreview(); _fn.build.form.zone.renderZonesPreview();
}, },
......
...@@ -50,34 +50,6 @@ ...@@ -50,34 +50,6 @@
class="coord y" class="coord y"
value="{{ y }}" /> value="{{ y }}" />
</div> </div>
<div class="alignment">
<label for="zone-{{index}}-align">
{{i18n "Alignment"}}
</label>
<select id="zone-{{index}}-align"
class="align-select"
aria-describedby="zone-align-description">
<option value=""
{{#ifeq align ""}}selected{{/ifeq}}>
{{i18n "none"}}
</option>
<option value="left"
{{#ifeq align "left"}}selected{{/ifeq}}>
{{i18n "left"}}
</option>
<option value="center"
{{#ifeq align "center"}}selected{{/ifeq}}>
{{i18n "center"}}
</option>
<option value="right"
{{#ifeq align "right"}}selected{{/ifeq}}>
{{i18n "right"}}
</option>
</select>
<div id="zone-align-description" class="zones-form-help">
{{i18n "Align dropped items to the left, center, or right. Default is no alignment (items stay exactly where the user drops them)."}}
</div>
</div>
</div> </div>
</script> </script>
......
{
"zones": [
{
"index": 1,
"title": "Zone No Align",
"width": 200,
"height": 100,
"x": 0,
"y": 0,
"align": "",
"id": "zone-none"
},
{
"index": 1,
"title": "Zone Invalid Align",
"width": 200,
"height": 100,
"x": 0,
"y": 100,
"align": "invalid",
"id": "zone-invalid"
},
{
"index": 2,
"title": "Zone Left Align",
"width": 200,
"height": 100,
"x": 0,
"y": 200,
"align": "left",
"id": "zone-left"
},
{
"index": 3,
"title": "Zone Right Align",
"width": 200,
"height": 100,
"x": 0,
"y": 300,
"align": "right",
"id": "zone-right"
},
{
"index": 4,
"title": "Zone Center Align",
"width": 200,
"height": 100,
"x": 0,
"y": 400,
"align": "center",
"id": "zone-center"
}
],
"items": [
{
"displayName": "AAAA",
"feedback": {
"incorrect": "No",
"correct": "Yes"
},
"zone": "Zone No Align",
"imageURL": "",
"id": 0
},
{
"displayName": "AAAA",
"feedback": {
"incorrect": "No",
"correct": "Yes"
},
"zone": "Zone No Align",
"imageURL": "",
"id": 1
},
{
"displayName": "AAAA",
"feedback": {
"incorrect": "No",
"correct": "Yes"
},
"zone": "Zone No Align",
"imageURL": "",
"id": 2
},
{
"displayName": "BBBB",
"feedback": {
"incorrect": "No",
"correct": "Yes"
},
"zone": "Zone Invalid Align",
"imageURL": "",
"id": 3
},
{
"displayName": "BBBB",
"feedback": {
"incorrect": "No",
"correct": "Yes"
},
"zone": "Zone Invalid Align",
"imageURL": "",
"id": 4
},
{
"displayName": "BBBB",
"feedback": {
"incorrect": "No",
"correct": "Yes"
},
"zone": "Zone Invalid Align",
"imageURL": "",
"id": 5
},
{
"displayName": "CCCC",
"feedback": {
"incorrect": "No",
"correct": "Yes"
},
"zone": "Zone Left Align",
"imageURL": "",
"id": 6
},
{
"displayName": "CCCC",
"feedback": {
"incorrect": "No",
"correct": "Yes"
},
"zone": "Zone Left Align",
"imageURL": "",
"id": 7
},
{
"displayName": "CCCC",
"feedback": {
"incorrect": "No",
"correct": "Yes"
},
"zone": "Zone Left Align",
"imageURL": "",
"id": 8
},
{
"displayName": "DDDD",
"feedback": {
"incorrect": "No",
"correct": "Yes"
},
"zone": "Zone Right Align",
"imageURL": "",
"id": 9
},
{
"displayName": "DDDD",
"feedback": {
"incorrect": "No",
"correct": "Yes"
},
"zone": "Zone Right Align",
"imageURL": "",
"id": 10
},
{
"displayName": "DDDD",
"feedback": {
"incorrect": "No",
"correct": "Yes"
},
"zone": "Zone Right Align",
"imageURL": "",
"id": 11
},
{
"displayName": "EEEE",
"feedback": {
"incorrect": "No",
"correct": "Yes"
},
"zone": "Zone Center Align",
"imageURL": "",
"id": 12
},
{
"displayName": "EEEE",
"feedback": {
"incorrect": "No",
"correct": "Yes"
},
"zone": "Zone Center Align",
"imageURL": "",
"id": 13
},
{
"displayName": "EEEE",
"feedback": {
"incorrect": "No",
"correct": "Yes"
},
"zone": "Zone Center Align",
"imageURL": "",
"id": 14
},
],
"feedback": {
"start": "Intro",
"finish": "Final"
},
}
...@@ -91,13 +91,6 @@ class BaseIntegrationTest(SeleniumBaseTest): ...@@ -91,13 +91,6 @@ class BaseIntegrationTest(SeleniumBaseTest):
def scroll_down(self, pixels=50): def scroll_down(self, pixels=50):
self.browser.execute_script("$(window).scrollTop({})".format(pixels)) self.browser.execute_script("$(window).scrollTop({})".format(pixels))
def _get_style(self, selector, style, computed=True):
if computed:
query = 'return getComputedStyle($("{selector}").get(0)).{style}'
else:
query = 'return $("{selector}").get(0).style.{style}'
return self.browser.execute_script(query.format(selector=selector, style=style))
@staticmethod @staticmethod
def get_element_html(element): def get_element_html(element):
return element.get_attribute('innerHTML').strip() return element.get_attribute('innerHTML').strip()
......
...@@ -120,12 +120,8 @@ class InteractionTestBase(object): ...@@ -120,12 +120,8 @@ class InteractionTestBase(object):
def send_input(self, item_value, value): def send_input(self, item_value, value):
element = self._get_item_by_value(item_value) element = self._get_item_by_value(item_value)
self.wait_until_visible(element) self.wait_until_visible(element)
input_element = element.find_element_by_class_name('input') element.find_element_by_class_name('input').send_keys(value)
self.wait_until_visible(input_element) element.find_element_by_class_name('submit-input').click()
input_element.send_keys(value)
submit_element = element.find_element_by_class_name('submit-input')
self.wait_until_visible(submit_element)
submit_element.click()
def assert_grabbed_item(self, item): def assert_grabbed_item(self, item):
self.assertEqual(item.get_attribute('aria-grabbed'), 'true') self.assertEqual(item.get_attribute('aria-grabbed'), 'true')
...@@ -134,9 +130,7 @@ class InteractionTestBase(object): ...@@ -134,9 +130,7 @@ class InteractionTestBase(object):
item = self._get_placed_item_by_value(item_value) item = self._get_placed_item_by_value(item_value)
self.wait_until_visible(item) self.wait_until_visible(item)
item_content = item.find_element_by_css_selector('.item-content') item_content = item.find_element_by_css_selector('.item-content')
self.wait_until_visible(item_content)
item_description = item.find_element_by_css_selector('.sr') item_description = item.find_element_by_css_selector('.sr')
self.wait_until_visible(item_description)
item_description_id = '-item-{}-description'.format(item_value) item_description_id = '-item-{}-description'.format(item_value)
self.assertIsNone(item.get_attribute('tabindex')) self.assertIsNone(item.get_attribute('tabindex'))
...@@ -587,90 +581,3 @@ class MultipleBlocksDataInteraction(InteractionTestBase, BaseIntegrationTest): ...@@ -587,90 +581,3 @@ class MultipleBlocksDataInteraction(InteractionTestBase, BaseIntegrationTest):
# Test mouse and keyboard interaction # Test mouse and keyboard interaction
self.interact_with_keyboard_help(scroll_down=900) self.interact_with_keyboard_help(scroll_down=900)
self.interact_with_keyboard_help(scroll_down=0, use_keyboard=True) self.interact_with_keyboard_help(scroll_down=0, use_keyboard=True)
@ddt
class ZoneAlignInteractionTest(InteractionTestBase, BaseIntegrationTest):
"""
Verifying Drag and Drop XBlock interactions using zone alignment.
"""
PAGE_TITLE = 'Drag and Drop v2'
PAGE_ID = 'drag_and_drop_v2'
ACTION_KEYS = (None, Keys.RETURN, Keys.SPACE, Keys.CONTROL+'m', Keys.COMMAND+'m')
def setUp(self):
super(ZoneAlignInteractionTest, self).setUp()
def _get_scenario_xml(self):
return self._get_custom_scenario_xml("data/test_zone_align.json")
def _assert_zone_align_item(self, item_id, zone_id, align, action_key=None):
"""
Test items placed in a zone with the given align setting.
Ensure that they are children of the zone.
"""
# parent container has the expected alignment
item_wrapper_selector = "div[data-zone='{zone_id}'] .item-wrapper".format(zone_id=zone_id)
self.assertEquals(self._get_style(item_wrapper_selector, 'textAlign'), align)
# Items placed in zones with align setting are children of the zone
zone_item_selector = '{item_wrapper_selector} .option'.format(item_wrapper_selector=item_wrapper_selector)
prev_placed_items = self._page.find_elements_by_css_selector(zone_item_selector)
self.place_item(item_id, zone_id, action_key)
placed_items = self._page.find_elements_by_css_selector(zone_item_selector)
self.assertEquals(len(placed_items), len(prev_placed_items) + 1)
# Not children of the target
target_item = '.target > .option'
self.assertEquals(len(self._page.find_elements_by_css_selector(target_item)), 0)
# Aligned items are relative positioned, with no transform or top/left
self.assertEquals(self._get_style(zone_item_selector, 'position'), 'relative')
self.assertEquals(self._get_style(zone_item_selector, 'transform'), 'none')
self.assertEquals(self._get_style(zone_item_selector, 'left'), '0px')
self.assertEquals(self._get_style(zone_item_selector, 'top'), '0px')
# Center-aligned items are display block
if align == 'center':
self.assertEquals(self._get_style(zone_item_selector, 'display'), 'block')
# but other aligned items are just inline-block
else:
self.assertEquals(self._get_style(zone_item_selector, 'display'), 'inline-block')
def test_no_zone_align(self):
"""
Test items placed in a zone with no align setting.
Ensure that they are children of div.target, not the zone.
"""
zone_id = "Zone No Align"
self.place_item(0, zone_id)
zone_item_selector = "div[data-zone='{zone_id}'] .item-wrapper .option".format(zone_id=zone_id)
self.assertEquals(len(self._page.find_elements_by_css_selector(zone_item_selector)), 0)
target_item_selector = '.target > .option'
placed_items = self._page.find_elements_by_css_selector(target_item_selector)
self.assertEquals(len(placed_items), 1)
self.assertEquals(placed_items[0].get_attribute('data-value'), '0')
# Non-aligned items are absolute positioned, with top/bottom set to px
self.assertEquals(self._get_style(target_item_selector, 'position'), 'absolute')
self.assertRegexpMatches(self._get_style(target_item_selector, 'left'), r'^\d+(\.\d+)?px$')
self.assertRegexpMatches(self._get_style(target_item_selector, 'top'), r'^\d+(\.\d+)?px$')
@data(
([3, 4, 5], "Zone Invalid Align", "start"),
([6, 7, 8], "Zone Left Align", "left"),
([9, 10, 11], "Zone Right Align", "right"),
([12, 13, 14], "Zone Center Align", "center"),
)
@unpack
def test_zone_align(self, items, zone, alignment):
reset = self._get_reset_button()
for item in items:
for action_key in self.ACTION_KEYS:
self._assert_zone_align_item(item, zone, alignment, action_key)
# Reset exercise
self.scroll_down(pixels=200)
reset.click()
self.scroll_down(pixels=0)
...@@ -65,6 +65,13 @@ class TestDragAndDropRender(BaseIntegrationTest): ...@@ -65,6 +65,13 @@ class TestDragAndDropRender(BaseIntegrationTest):
self.browser.get(self.live_server_url) self.browser.get(self.live_server_url)
self._page = self.go_to_page(self.PAGE_TITLE) self._page = self.go_to_page(self.PAGE_TITLE)
def _get_style(self, selector, style, computed=True):
if computed:
query = 'return getComputedStyle($("{selector}").get(0)).{style}'
else:
query = 'return $("{selector}").get(0).style.{style}'
return self.browser.execute_script(query.format(selector=selector, style=style))
def _assert_box_percentages(self, selector, left, top, width, height): def _assert_box_percentages(self, selector, left, top, width, height):
""" Assert that the element 'selector' has the specified position/size percentages """ """ Assert that the element 'selector' has the specified position/size percentages """
values = {key: self._get_style(selector, key, False) for key in ['left', 'top', 'width', 'height']} values = {key: self._get_style(selector, key, False) for key in ['left', 'top', 'width', 'height']}
...@@ -181,7 +188,6 @@ class TestDragAndDropRender(BaseIntegrationTest): ...@@ -181,7 +188,6 @@ class TestDragAndDropRender(BaseIntegrationTest):
self.assertEqual(zone.get_attribute('dropzone'), 'move') self.assertEqual(zone.get_attribute('dropzone'), 'move')
self.assertEqual(zone.get_attribute('aria-dropeffect'), 'move') self.assertEqual(zone.get_attribute('aria-dropeffect'), 'move')
self.assertEqual(zone.get_attribute('data-zone'), 'Zone {}'.format(zone_number)) self.assertEqual(zone.get_attribute('data-zone'), 'Zone {}'.format(zone_number))
self.assertEqual(zone.get_attribute('data-zonealign'), 'none')
self.assertIn('ui-droppable', self.get_element_classes(zone)) self.assertIn('ui-droppable', self.get_element_classes(zone))
zone_box_percentages = box_percentages[index] zone_box_percentages = box_percentages[index]
self._assert_box_percentages( # pylint: disable=star-args self._assert_box_percentages( # pylint: disable=star-args
...@@ -266,31 +272,3 @@ class TestDragAndDropRender(BaseIntegrationTest): ...@@ -266,31 +272,3 @@ class TestDragAndDropRender(BaseIntegrationTest):
for zone in zones: for zone in zones:
zone_name = zone.find_element_by_css_selector('p.zone-name') zone_name = zone.find_element_by_css_selector('p.zone-name')
self.assertNotIn('sr', zone_name.get_attribute('class')) self.assertNotIn('sr', zone_name.get_attribute('class'))
@ddt
class TestDragAndDropRenderZoneAlign(BaseIntegrationTest):
"""
Verifying Drag and Drop XBlock rendering using zone alignment.
"""
PAGE_TITLE = 'Drag and Drop v2'
PAGE_ID = 'drag_and_drop_v2'
def setUp(self):
super(TestDragAndDropRenderZoneAlign, self).setUp()
scenario_xml = self._get_custom_scenario_xml("data/test_zone_align.json")
self._add_scenario(self.PAGE_ID, self.PAGE_TITLE, scenario_xml)
self._page = self.go_to_page(self.PAGE_TITLE)
def test_zone_align(self):
expected_alignments = {
"#-zone-none": "start",
"#-zone-invalid": "start",
"#-zone-left": "left",
"#-zone-right": "right",
"#-zone-center": "center"
}
for zone_id, expected_alignment in expected_alignments.items():
selector = "{zone_id} .item-wrapper".format(zone_id=zone_id)
self.assertEquals(self._get_style(selector, "textAlign"), expected_alignment)
self.assertEquals(self._get_style(selector, "textAlign", computed=True), expected_alignment)
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