diff --git a/.travis.yml b/.travis.yml index 9ae664b6a..71d24609c 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ install: - "sh install_test_deps.sh" - "pip uninstall -y xblock-drag-and-drop-v2" - "python setup.py sdist" - - "pip install dist/xblock-drag-and-drop-v2-2.0.1.tar.gz" + - "pip install dist/xblock-drag-and-drop-v2-2.0.2.tar.gz" script: - pep8 drag_and_drop_v2 tests --max-line-length=120 - pylint drag_and_drop_v2 tests diff --git a/Changelog.md b/Changelog.md new file mode 100644 index 000000000..e2a74a72a --- /dev/null +++ b/Changelog.md @@ -0,0 +1,21 @@ +Version 2.0.2 (2016-02-18) +-------------------------- + +* Bugfix: "Background description" was required, but if you filled it out and pressed "Continue", "Save", it would accept the new description but would not actually save it. (PR #55) +* Bugfix: When configuring the draggable items, the "Image Description" was always required, even if the "Image URL" was blank. (PR #55) +* Bugfix: When clicking certain action links in the dndv2 editor (e.g. "Add a Zone"), the browser would scroll to the top of the page (since the href="#" event was not prevented). (PR #55) +* Bugfix: When changing tabs in the dndv2 editor, the next tab would often be scrolled down halfway. (PR #55) +* Bugfix: In Studio, Newly added drag and drop components did not load properly, due to [a Studio bug](https://github.com/edx/edx-platform/pull/11433) that affects Cypress and Dogwood. (Fixed in Studio post-Dogwood.) (PR #55) +* Fixed some flaky tests + + +Version 2.0.1 (2016-02-15) +-------------------------- +* Bugfix: If zone labels are numbers, like "1", "2", etc., then the draggables would not match with that zone (you cannot drop the draggables onto that zone) (PR #54) +* Bugfix: If two zones had the same name/label, the block would not work properly. (PR #54) +* Bugfix: If the platform's locale is set to a language like "de" or "eo" that formats numbers like "3,14", then the "Maximum Score" field appears blank when editing a dndv2 exercise in Studio. Attempting to save the exercise with that field blank causes a 500. (PR #54) + +Version 2.0.0 (2016-01-29) +------------------------ + +A brand new release of the Drag and Drop XBlock, featuring major UX improvements, new features, and accessibility enhancements. diff --git a/setup.py b/setup.py index 936c89824..ab28a60b7 100644 --- a/setup.py +++ b/setup.py @@ -23,7 +23,7 @@ def package_data(pkg, root_list): setup( name='xblock-drag-and-drop-v2', - version='2.0.1', + version='2.0.2', description='XBlock - Drag-and-Drop v2', packages=['drag_and_drop_v2'], install_requires=[ diff --git a/tests/integration/test_interaction.py b/tests/integration/test_interaction.py index 71c06b825..955211ded 100644 --- a/tests/integration/test_interaction.py +++ b/tests/integration/test_interaction.py @@ -122,7 +122,12 @@ def move_item_to_zone(self, item_value, zone_id, action_key): def send_input(self, item_value, value): element = self._get_item_by_value(item_value) self.wait_until_visible(element) - element.find_element_by_class_name('input').send_keys(value) + # Since virtual-dom may be updating DOM elements by replacing them completely, the + # following method must be used to wait for the input box to appear: + textbox_visible_selector = '.numerical-input[style*="display: block"] input' + self.wait_until_exists(textbox_visible_selector) + textbox = self._page.find_element_by_css_selector(textbox_visible_selector) + textbox.send_keys(value) element.find_element_by_class_name('submit-input').click() def assert_grabbed_item(self, item): diff --git a/tests/integration/test_sizing.py b/tests/integration/test_sizing.py index 31dec0d22..10e3b5343 100644 --- a/tests/integration/test_sizing.py +++ b/tests/integration/test_sizing.py @@ -90,7 +90,7 @@ def _get_scenario_xml(): # A 400x300 image with automatic sizing should be constrained to the maximum width Expectation(item_id=5, zone_id=ZONE_50, width_percent=AUTO_MAX_WIDTH), # A 200x200 image with automatic sizing - Expectation(item_id=6, zone_id=ZONE_50, width_percent=[25, 30]), + Expectation(item_id=6, zone_id=ZONE_50, width_percent=[25, 30.2]), # A 400x300 image with a specified width of 50% Expectation(item_id=7, zone_id=ZONE_50, fixed_width_percent=50), # A 200x200 image with a specified width of 50% @@ -112,6 +112,17 @@ def _size_for_mobile(self): self.browser.set_window_size(375, 627) # iPhone 6 viewport size wait = WebDriverWait(self.browser, 2) wait.until(lambda browser: browser.get_window_size()["width"] == 375) + # Fix platform inconsistencies caused by scrollbar size: + self.browser.execute_script('$("body").css("margin-right", "40px")') + scrollbar_width = self.browser.execute_script( + "var $outer = $('
').css({visibility: 'hidden', width: 100, overflow: 'scroll'}).appendTo('body');" + "var widthWithScroll = $('
').css({width: '100%'}).appendTo($outer).outerWidth();" + "$outer.remove();" + "return 100 - widthWithScroll;" + ) + self.browser.execute_script('$(".wrapper-workbench").css("margin-right", "-{}px")'.format(40 + scrollbar_width)) + # And reduce the wasted space around our XBlock in the workbench: + self.browser.execute_script('return $(".workbench .preview").css("margin", "0")') def test_wide_image_mobile(self): """ Test the upper, larger, wide image in a mobile-sized window """ @@ -121,7 +132,7 @@ def test_wide_image_mobile(self): def test_square_image_mobile(self): """ Test the lower, smaller, square image in a mobile-sized window """ self._size_for_mobile() - self._check_sizes(1, self.EXPECTATIONS, expected_img_width=375, is_desktop=False) + self._check_sizes(1, self.EXPECTATIONS, is_desktop=False) def _check_width(self, item_description, item, container_width, expected_percent): """ @@ -129,19 +140,20 @@ def _check_width(self, item_description, item, container_width, expected_percent of container_width, or if expected_percent is a pair of numbers, that it is within that range. """ - width_percent = item.size["width"] / container_width * 100 + width_pixels = item.size["width"] + width_percent = width_pixels / container_width * 100 if isinstance(expected_percent, (list, tuple)): min_expected, max_expected = expected_percent - msg = "{} should have width of {}% - {}%. Actual: {:.2f}%".format( - item_description, min_expected, max_expected, width_percent + msg = "{} should have width of {}% - {}%. Actual: {}px ({:.2f}% of {}px)".format( + item_description, min_expected, max_expected, width_pixels, width_percent, container_width ) self.assertGreaterEqual(width_percent, min_expected, msg) self.assertLessEqual(width_percent, max_expected, msg) else: self.assertAlmostEqual( width_percent, expected_percent, delta=1, - msg="{} should have width of ~{}% (+/- 1%). Actual: {:.2f}%".format( - item_description, expected_percent, width_percent + msg="{} should have width of ~{}% (+/- 1%). Actual: {}px ({:.2f}% of {}px)".format( + item_description, expected_percent, width_pixels, width_percent, container_width ) ) @@ -165,7 +177,7 @@ def _check_img_pixel_dimensions(self, item_description, item, expect_w, expect_h ) ) - def _check_sizes(self, block_index, expectations, expected_img_width=755, is_desktop=True): + def _check_sizes(self, block_index, expectations, expected_img_width=None, is_desktop=True): """ Test the actual dimensions that each draggable has, in the bank and when placed """ # Check assumptions - the container wrapping this XBlock should be 770px wide self._switch_to_block(block_index) @@ -177,8 +189,12 @@ def _check_sizes(self, block_index, expectations, expected_img_width=755, is_des if is_desktop: # If using a desktop-sized window, we can know the exact dimensions of various containers: self.assertEqual(self._page.size["width"], 770) # self._page is the .xblock--drag-and-drop div - self.assertEqual(target_img_width, expected_img_width) + self.assertEqual(target_img_width, expected_img_width or 755) self.assertEqual(item_bank_width, 755) + else: + self.assertEqual(self._page.size["width"], 335) # self._page is the .xblock--drag-and-drop div + self.assertEqual(target_img_width, expected_img_width or 328) + self.assertEqual(item_bank_width, 328) # Test each element, before it is placed (while it is in the item bank). for expect in expectations: