Permalink
Browse files

Fix pending 'reorder redirects' cucumber test

  • Loading branch information...
1 parent b173726 commit f451cefe83fd05591b019f00e73538510120f460 @artemave artemave committed Mar 20, 2012
View
@@ -12,23 +12,23 @@ PATH
GEM
remote: http://rubygems.org/
specs:
- activemodel (3.2.1)
- activesupport (= 3.2.1)
+ activemodel (3.2.2)
+ activesupport (= 3.2.2)
builder (~> 3.0.0)
- activerecord (3.2.1)
- activemodel (= 3.2.1)
- activesupport (= 3.2.1)
- arel (~> 3.0.0)
+ activerecord (3.2.2)
+ activemodel (= 3.2.2)
+ activesupport (= 3.2.2)
+ arel (~> 3.0.2)
tzinfo (~> 0.3.29)
- activeresource (3.2.1)
- activemodel (= 3.2.1)
- activesupport (= 3.2.1)
- activesupport (3.2.1)
+ activeresource (3.2.2)
+ activemodel (= 3.2.2)
+ activesupport (= 3.2.2)
+ activesupport (3.2.2)
i18n (~> 0.6)
multi_json (~> 1.0)
addressable (2.2.7)
archive-tar-minitar (0.5.2)
- arel (3.0.0)
+ arel (3.0.2)
awesome_print (1.0.2)
builder (3.0.0)
capybara (1.1.2)
@@ -43,18 +43,18 @@ GEM
childprocess (0.3.1)
ffi (~> 1.0.6)
columnize (0.3.6)
- cucumber (1.1.4)
+ cucumber (1.1.9)
builder (>= 2.1.2)
diff-lcs (>= 1.1.2)
- gherkin (~> 2.7.1)
+ gherkin (~> 2.9.0)
json (>= 1.4.6)
term-ansicolor (>= 1.0.6)
daemons (1.1.8)
database_cleaner (0.7.1)
diff-lcs (1.1.3)
eventmachine (0.12.10)
ffi (1.0.11)
- gherkin (2.7.7)
+ gherkin (2.9.0)
json (>= 1.4.6)
growl (1.0.3)
guard (1.0.0)
@@ -72,12 +72,12 @@ GEM
addressable (~> 2.2.6)
linecache (0.46)
rbx-require-relative (> 0.0.4)
- linecache19 (0.5.13)
+ linecache19 (0.5.12)
ruby_core_source (>= 0.1.4)
mime-types (1.17.2)
- multi_json (1.0.4)
+ multi_json (1.1.0)
mysql2 (0.3.11)
- nokogiri (1.5.0)
+ nokogiri (1.5.2)
pg (0.13.2)
rack (1.4.1)
rack-protection (1.2.0)
@@ -87,7 +87,7 @@ GEM
rake (0.9.2.2)
rb-fsevent (0.9.0)
rb-readline (0.4.2)
- rbx-require-relative (0.0.5)
+ rbx-require-relative (0.0.9)
relish (0.5.3)
archive-tar-minitar (>= 0.5.2)
json (>= 1.4.6)
@@ -107,7 +107,7 @@ GEM
ruby-debug-base (~> 0.10.4.0)
ruby-debug-base (0.10.4)
linecache (>= 0.3)
- ruby-debug-base19 (0.11.26)
+ ruby-debug-base19 (0.11.25)
columnize (>= 0.3.1)
linecache19 (>= 0.5.11)
ruby_core_source (>= 0.1.4)
@@ -118,14 +118,14 @@ GEM
ruby_core_source (0.1.5)
archive-tar-minitar (>= 0.5.2)
rubyzip (0.9.6.1)
- selenium-webdriver (2.19.0)
+ selenium-webdriver (2.20.0)
childprocess (>= 0.2.5)
- ffi (~> 1.0.9)
- multi_json (~> 1.0.4)
+ ffi (~> 1.0)
+ multi_json (~> 1.0)
rubyzip
shoulda-matchers (1.0.0)
- simplecov (0.5.4)
- multi_json (~> 1.0.3)
+ simplecov (0.6.1)
+ multi_json (~> 1.0)
simplecov-html (~> 0.5.3)
simplecov-html (0.5.3)
sinatra (1.3.2)
@@ -146,7 +146,7 @@ GEM
rack (>= 1.0.0)
thor (0.14.6)
tilt (1.3.3)
- tzinfo (0.3.31)
+ tzinfo (0.3.32)
xpath (0.1.4)
nokogiri (~> 1.3)
@@ -46,19 +46,17 @@
end
When /^I reorder second redirect to be the first one$/ do
- handler = find("#redirects #redirect_#{RestAssured::Models::Redirect.last.id} td.handle")
- target = find('#redirects thead')
-
- handler.drag_to target
+ page.execute_script %{
+ $('#redirects #redirect_#{RestAssured::Models::Redirect.order('position').last.id}').simulateDragSortable({move: -1, handle: '.handle'})
+ }
+ sleep 2
end
Then /^"([^"]*)" should be redirected to "([^"]*)"$/ do |missing_request, url|
- pending('This does not pass due to Capybara/Selelium broken drag and drop support')
-
get missing_request
follow_redirect!
- last_request.url.should == "#{url}#{missing_request}"
+ last_request.url.should == url
end
Given /^blank slate$/ do
@@ -49,9 +49,9 @@ Feature: manage redirects via ui
| /api/bbb | http://twitter.com/api |
And I am on "redirects" page
When I reorder second redirect to be the first one
- Then "/api/bbb" should be redirected to "http://twitter.com/api"
+ Then "/api/bbb/ccc" should be redirected to "http://twitter.com/api/ccc"
When I reorder second redirect to be the first one
- Then "/api/bbb" should be redirected to "http://google.com/api"
+ Then "/api/bbb/ccc" should be redirected to "http://google.com/api"
@javascript
Scenario: delete redirect
@@ -1,3 +1,3 @@
module RestAssured
- VERSION = '1.1.2'
+ VERSION = '1.1.3'
end
@@ -0,0 +1,235 @@
+(function($) {
+ /*
+ * Simulate drag of a JQuery UI sortable list
+ * Repository: https://github.com/mattheworiordan/jquery.simulate.drag-sortable.js
+ * Author: http://mattheworiordan.com
+ *
+ * options are:
+ * - move: move item up (positive) or down (negative) by Integer amount
+ * - dropOn: move item to a new linked list, move option now represents position in the new list (zero indexed)
+ * - handle: selector for the draggable handle element (optional)
+ * - listItem: selector to limit which sibling items can be used for reordering
+ * - placeHolder: if a placeholder is used during dragging, we need to consider it's height
+ * - tolerance: (optional) number of pixels to overlap by instead of the default 50% of the element height
+ *
+ */
+ $.fn.simulateDragSortable = function(options) {
+ // build main options before element iteration
+ var opts = $.extend({}, $.fn.simulateDragSortable.defaults, options);
+
+ applyDrag = function(options) {
+ // allow for a drag handle if item is not draggable
+ var that = this,
+ options = options || opts, // default to plugin opts unless options explicitly provided
+ handle = options.handle ? $(this).find(options.handle)[0] : $(this)[0],
+ listItem = options.listItem,
+ placeHolder = options.placeHolder,
+ sibling = $(this),
+ moveCounter = Math.floor(options.move),
+ direction = moveCounter > 0 ? 'down' : 'up',
+ moveVerticalAmount = 0,
+ initialVerticalPosition = 0,
+ extraDrag = !isNaN(parseInt(options.tolerance, 10)) ? function() { return Number(options.tolerance); } : function(obj) { return ($(obj).outerHeight() / 2) + 5; },
+ dragPastBy = 0, // represents the additional amount one drags past an element and bounce back
+ dropOn = options.dropOn ? $(options.dropOn) : false,
+ center = findCenter(handle),
+ x = Math.floor(center.x),
+ y = Math.floor(center.y),
+ mouseUpAfter = (opts.debug ? 2500 : 10);
+
+ if (dropOn) {
+ if (dropOn.length === 0) {
+ if (console && console.log) { console.log('simulate.drag-sortable.js ERROR: Drop on target could not be found'); console.log(options.dropOn); }
+ return;
+ }
+ sibling = dropOn.find('>*:last');
+ moveCounter = -(dropOn.find('>*').length + 1) + (moveCounter + 1); // calculate length of list after this move, use moveCounter as a positive index position in list to reverse back up
+ if (dropOn.offset().top - $(this).offset().top < 0) {
+ // moving to a list above this list, so move to just above top of last item (tried moving to top but JQuery UI wouldn't bite)
+ initialVerticalPosition = sibling.offset().top - $(this).offset().top - extraDrag(this);
+ } else {
+ // moving to a list below this list, so move to bottom and work up (JQuery UI does not trigger new list below unless you move past top item first)
+ initialVerticalPosition = sibling.offset().top - $(this).offset().top - $(this).height();
+ }
+ } else if (moveCounter === 0) {
+ if (console && console.log) { console.log('simulate.drag-sortable.js WARNING: Drag with move set to zero has no effect'); }
+ return;
+ } else {
+ while (moveCounter !== 0) {
+ if (direction === 'down') {
+ if (sibling.next(listItem).length) {
+ sibling = sibling.next(listItem);
+ moveVerticalAmount += sibling.outerHeight();
+ }
+ moveCounter -= 1;
+ } else {
+ if (sibling.prev(listItem).length) {
+ sibling = sibling.prev(listItem);
+ moveVerticalAmount -= sibling.outerHeight();
+ }
+ moveCounter += 1;
+ }
+ }
+ }
+
+ dispatchEvent(handle, 'mousedown', createEvent('mousedown', handle, { clientX: x, clientY: y }));
+ // simulate drag start
+ dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x+1, clientY: y+1 }));
+
+ if (dropOn) {
+ // jump to top or bottom of new list but do it in increments so that JQuery UI registers the drag events
+ slideUpTo(x, y, initialVerticalPosition);
+
+ // reset y position to top or bottom of list and move from there
+ y += initialVerticalPosition;
+
+ // now call regular shift/down in a list
+ options = jQuery.extend(options, { move: moveCounter });
+ delete options.dropOn;
+
+ // add some delays to allow JQuery UI to catch up
+ setTimeout(function() {
+ dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y }));
+ }, 5);
+ setTimeout(function() {
+ dispatchEvent(handle, 'mouseup', createEvent('mouseup', handle, { clientX: x, clientY: y }));
+ setTimeout(function() {
+ if (options.move) {
+ applyDrag.call(that, options);
+ }
+ }, 5);
+ }, mouseUpAfter);
+
+ // stop execution as applyDrag has been called again
+ return;
+ }
+
+ // Sortable is using a fixed height placeholder meaning items jump up and down as you drag variable height items into fixed height placeholder
+ placeHolder = placeHolder && $(this).parent().find(placeHolder);
+
+ if (!placeHolder && (direction === 'down')) {
+ // need to move at least as far as this item and or the last sibling
+ if ($(this).outerHeight() > $(sibling).outerHeight()) {
+ moveVerticalAmount += $(this).outerHeight() - $(sibling).outerHeight();
+ }
+ moveVerticalAmount += extraDrag(sibling);
+ dragPastBy += extraDrag(sibling);
+ } else if (direction === 'up') {
+ // move a little extra to ensure item clips into next position
+ moveVerticalAmount -= Math.max(extraDrag(this), 5);
+ } else if (direction === 'down') {
+ // moving down with a place holder
+ if (placeHolder.height() < $(this).height()) {
+ moveVerticalAmount += Math.max(placeHolder.height(), 5);
+ } else {
+ moveVerticalAmount += extraDrag(sibling);
+ }
+ }
+
+ if (sibling[0] !== $(this)[0]) {
+ // step through so that the UI controller can determine when to show the placeHolder
+ slideUpTo(x, y, moveVerticalAmount, dragPastBy);
+ } else {
+ if (window.console) {
+ console.log('simulate.drag-sortable.js WARNING: Could not move as at top or bottom already');
+ }
+ }
+
+ setTimeout(function() {
+ dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y + moveVerticalAmount }));
+ }, 5);
+ setTimeout(function() {
+ dispatchEvent(handle, 'mouseup', createEvent('mouseup', handle, { clientX: x, clientY: y + moveVerticalAmount }));
+ }, mouseUpAfter);
+ };
+
+ // iterate and move each matched element
+ return this.each(applyDrag);
+ };
+
+ // fire mouse events, go half way, then the next half, so small mouse movements near target and big at the start
+ function slideUpTo(x, y, targetOffset, goPastBy) {
+ var moveBy, offset;
+
+ if (!goPastBy) { goPastBy = 0; }
+ if ((targetOffset < 0) && (goPastBy > 0)) { goPastBy = -goPastBy; } // ensure go past is in the direction as often passed in from object height so always positive
+
+ // go forwards including goPastBy
+ for (offset = 0; Math.abs(offset) + 1 < Math.abs(targetOffset + goPastBy); offset += ((targetOffset + goPastBy - offset)/2) ) {
+ dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y + Math.ceil(offset) }));
+ }
+ offset = targetOffset + goPastBy;
+ dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y + offset }));
+
+ // now bounce back
+ for (; Math.abs(offset) - 1 >= Math.abs(targetOffset); offset += ((targetOffset - offset)/2) ) {
+ dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y + Math.ceil(offset) }));
+ }
+ dispatchEvent(document, 'mousemove', createEvent('mousemove', document, { clientX: x, clientY: y + targetOffset }));
+ }
+
+ function createEvent(type, target, options) {
+ var evt;
+ var e = $.extend({
+ target: target,
+ preventDefault: function() { },
+ stopImmediatePropagation: function() { },
+ stopPropagation: function() { },
+ isPropagationStopped: function() { return true; },
+ isImmediatePropagationStopped: function() { return true; },
+ isDefaultPrevented: function() { return true; },
+ bubbles: true,
+ cancelable: (type != "mousemove"),
+ view: window,
+ detail: 0,
+ screenX: 0,
+ screenY: 0,
+ clientX: 0,
+ clientY: 0,
+ ctrlKey: false,
+ altKey: false,
+ shiftKey: false,
+ metaKey: false,
+ button: 0,
+ relatedTarget: undefined
+ }, options || {});
+
+ if ($.isFunction(document.createEvent)) {
+ evt = document.createEvent("MouseEvents");
+ evt.initMouseEvent(type, e.bubbles, e.cancelable, e.view, e.detail,
+ e.screenX, e.screenY, e.clientX, e.clientY,
+ e.ctrlKey, e.altKey, e.shiftKey, e.metaKey,
+ e.button, e.relatedTarget || document.body.parentNode);
+ } else if (document.createEventObject) {
+ evt = document.createEventObject();
+ $.extend(evt, e);
+ evt.button = { 0:1, 1:4, 2:2 }[evt.button] || evt.button;
+ }
+ return evt;
+ }
+
+ function dispatchEvent(el, type, evt) {
+ if (el.dispatchEvent) {
+ el.dispatchEvent(evt);
+ } else if (el.fireEvent) {
+ el.fireEvent('on' + type, evt);
+ }
+ return evt;
+ }
+
+ function findCenter(el) {
+ var elm = $(el),
+ o = elm.offset();
+ return {
+ x: o.left + elm.outerWidth() / 2,
+ y: o.top + elm.outerHeight() / 2
+ };
+ }
+
+ //
+ // plugin defaults
+ //
+ $.fn.simulateDragSortable.defaults = {
+ move: 0
+ };
+})(jQuery);
Oops, something went wrong.

0 comments on commit f451cef

Please sign in to comment.