2016-08-12 139 views
3

我在量角器测试中(像其他人一样)拖放有问题,但不是一般 - 只在使用HTML5的角度应用程序内。量角器拖放:角度与角度与HTML5

为了演示,我写了一个使用两个网页展示拖放功能的小型量角器测试套件。 第一页(用于第一个测试用例)演示了AngualarJS中jQueryUI拖放功能的实现。这一个工作得很好。 第二页(在第二个测试用例中使用)使用角度拖动&删除HTML5。这个在我的测试中不起作用。

我的下一个尝试是使用一个辅助功能这个帖子给我带来了太多:https://gist.github.com/druska/624501b7209a74040175 Unfortunaly这并不没有为我工作neighter作为我的第三个测试显示

谁能告诉我,为什么拖&降随HTML 5不起作用,我必须做些什么才能使其运行?

提前感谢

Akki

我的系统:

  • 量角器4.0.0
  • 硒的服务器独立2.53.1
  • chromedriver 2.22
  • iedriver 2.53.1
  • geckodriver 0.9.0

我的测试套件:

describe('Protractor drag-and-drop test', function() { 

    afterEach(function(){ 
     browser.sleep(5000); 
    }); 

    it('1st test - jQueryUI drag and drop for AngularJS', function() { 
     //found here: http://stackoverflow.com/questions/24315571/drag-drop-with-protractor-by-repeater 
     browser.get('http://codef0rmer.github.io/angular-dragdrop/#!/'); 
     var elem = element(by.css('.ui-draggable')); 
     var target = element(by.css('.thumbnail')); 
     browser.sleep(3000); 

     elem.click(); 
     browser.actions().dragAndDrop(elem, target).perform(); 
    }); 

    it('2nd test - Angular drag & drop with HTML5', function() { 
     browser.get('http://marceljuenemann.github.io/angular-drag-and-drop-lists/demo/#/simple'); 

     var elem =element.all(by.xpath("/html/body/div[2]/div[2]/div[2]/div[1]/div[1]/div[2]/div/div[2]/ul/li[1]")).first(); 
     var target = $('ul[dnd-list=list]'); 

     expect(elem.getText()).toEqual("Item B1"); //Item that should be dragged and dropped 
     expect(target.getText()).toContain("Item A1"); //element sorrounding "ItemA1", "Item A2", "ItemA3" 

     elem.click();  
     browser.actions().dragAndDrop(elem, target).perform(); 
    }); 

    it('3rd test - Angular drag & drop with HTML5 with native_js_drag_and_drop_helper', function() { 
     browser.get('http://marceljuenemann.github.io/angular-drag-and-drop-lists/demo/#/simple'); 
     var dragAndDropFn = require('./native_js_drag_and_drop_helper.js'); 

     var elem =element.all(by.xpath("/html/body/div[2]/div[2]/div[2]/div[1]/div[1]/div[2]/div/div[2]/ul/li[1]")).first(); 
     var target = $('ul[dnd-list=list]'); 

     expect(elem.getText()).toEqual("Item B1"); //Item that should be dragged and dropped 
     expect(target.getText()).toContain("Item A1"); //element sorrounding "ItemA1", "Item A2", "ItemA3" 

     elem.click();  
     browser.executeScript(dragAndDropFn, target.getWebElement(), elem.getWebElement()); 
    }); 

    xit(' 4th test - Test of native drag and drop helper ', function() { 
     // test found on https://gist.github.com/druska/624501b7209a74040175 failing with "Angular could not be found on the page http://html5demos.com/drag : retries looking for angular exceeded" 
     var dragAndDropFn = require('./native_js_drag_and_drop_helper.js'); 
     browser.get("http://html5demos.com/drag"); 
     var field = element.all(by.className('drag-handle')).get(0); 
     var src = element.all(by.className('box-list-compact-hover')).get(0); 
     browser.executeScript(dragAndDropFn, field.getWebElement(), src.getWebElement()); 
    }, 120000); 
}); 

我的配置文件:

exports.config = { 
seleniumAddress: 'http://localhost:4444/wd/hub', 
specs: ['spec.js'], 
capabilities: { 
    //browserName: 'internet explorer' 
    browserName: 'chrome' 
    //browserName: 'firefox' 
    }, 
}; 

的native_js_drag_and_drop_helper:

module.exports = function simulateDragDrop(sourceNode, destinationNode) { 
var EVENT_TYPES = { 
    DRAG_END: 'dragend', 
    DRAG_START: 'dragstart', 
    DROP: 'drop' 
} 

function createCustomEvent(type) { 
    var event = new CustomEvent("CustomEvent") 
    event.initCustomEvent(type, true, true, null) 
    event.dataTransfer = { 
     data: { 
     }, 
     setData: function(type, val) { 
      this.data[type] = val 
     }, 
     getData: function(type) { 
      return this.data[type] 
     } 
    } 
    return event 
} 

function dispatchEvent(node, type, event) { 
    if (node.dispatchEvent) { 
     return node.dispatchEvent(event) 
    } 
    if (node.fireEvent) { 
     return node.fireEvent("on" + type, event) 
    } 
} 

var event = createCustomEvent(EVENT_TYPES.DRAG_START) 
dispatchEvent(sourceNode, EVENT_TYPES.DRAG_START, event) 

var dropEvent = createCustomEvent(EVENT_TYPES.DROP) 
dropEvent.dataTransfer = event.dataTransfer 
dispatchEvent(destinationNode, EVENT_TYPES.DROP, dropEvent) 

var dragEndEvent = createCustomEvent(EVENT_TYPES.DRAG_END) 
dragEndEvent.dataTransfer = event.dataTransfer 
dispatchEvent(sourceNode, EVENT_TYPES.DRAG_END, dragEndEvent) 
} 

回答

0

注知道这是否有什么不同,但我我使用了一个ActionSequence电话而不仅仅是Action,在我们的Angular应用程序中拖放项目似乎对我来说工作得很好。这不是在处理HTML5,虽然不知道这是否有所作为。

而且这是前一阵子,所以这一次可能不再有效,但你可以尝试这样的:

// 1。获取屏幕 baItems.listOfMeasurementMethods.then(函数(元素){

  //Only perform drag and drops if there is more than one measurement method 
      if (elements.length > 1) { 
       var val1 = baItems.getLists();  //get the current text order 

       console.log(elements.length); 
       baItems.dragAndDrop(elements[0], elements[elements.length - 1]); //drag element 0 to last element and drop it 
       helpers.sleepX(15000); 

       var val2 = baItems.getLists(); //get the new text order 

       expect(val2).not.toBe(val1); //expect that they are not the same (i.e. they have been dragged and dropped) 
      } 
      else { 
       console.log('Only one measurement method - cant change order'); 
      } 

,然后拖动上的所有测量方法拖拽元素的列表,并为我看起来像

this.dragAndDrop = function (dragFromElement, dropToElement) { 
    //console.log('inside dragAndDrop()'); 
    new protractor.ActionSequence(browser). 
      click(dragFromElement). 
      dragAndDrop(dragFromElement.getLocation(), dropToElement.getLocation()). 
      perform(); 
} 
0

我滴法几天前还经历了这种情况,native_js_drag_and_drop_helper.js也没有为我工作...... 然后我开始了解关于simulate.js api我已经使用它的代码,幸运的是我为我工作...对于dragdrop.js

module.exports = function (dragEleSelector, dropEleSelector) { 
 
    (function ($, undefined) { 
 
     var rkeyEvent = /^key/, 
 
      rmouseEvent = /^(?:mouse|contextmenu)|click/; 
 

 
     $.fn.simulate = function (type, options) { 
 
      return this.each(function() { 
 
       new $.simulate(this, type, options); 
 
      }); 
 
     }; 
 

 
     $.simulate = function (elem, type, options) { 
 
      var method = $.camelCase("simulate-" + type); 
 

 
      this.target = elem; 
 
      this.options = options; 
 

 
      if (this[ method ]) { 
 
       this[ method ](); 
 
      } else { 
 
       this.simulateEvent(elem, type, options); 
 
      } 
 
     }; 
 

 
     $.extend($.simulate, { 
 
      keyCode: { 
 
       BACKSPACE: 8, 
 
       COMMA: 188, 
 
       DELETE: 46, 
 
       DOWN: 40, 
 
       END: 35, 
 
       ENTER: 13, 
 
       ESCAPE: 27, 
 
       HOME: 36, 
 
       LEFT: 37, 
 
       NUMPAD_ADD: 107, 
 
       NUMPAD_DECIMAL: 110, 
 
       NUMPAD_DIVIDE: 111, 
 
       NUMPAD_ENTER: 108, 
 
       NUMPAD_MULTIPLY: 106, 
 
       NUMPAD_SUBTRACT: 109, 
 
       PAGE_DOWN: 34, 
 
       PAGE_UP: 33, 
 
       PERIOD: 190, 
 
       RIGHT: 39, 
 
       SPACE: 32, 
 
       TAB: 9, 
 
       UP: 38 
 
      }, 
 

 
      buttonCode: { 
 
       LEFT: 0, 
 
       MIDDLE: 1, 
 
       RIGHT: 2 
 
      } 
 
     }); 
 

 
     $.extend($.simulate.prototype, { 
 

 
      simulateEvent: function (elem, type, options) { 
 
       var event = this.createEvent(type, options); 
 
       this.dispatchEvent(elem, type, event, options); 
 
      }, 
 

 
      createEvent: function (type, options) { 
 
       if (rkeyEvent.test(type)) { 
 
        return this.keyEvent(type, options); 
 
       } 
 

 
       if (rmouseEvent.test(type)) { 
 
        return this.mouseEvent(type, options); 
 
       } 
 
      }, 
 

 
      mouseEvent: function (type, options) { 
 
       var event, eventDoc, doc, body; 
 
       options = $.extend({ 
 
        bubbles: true, 
 
        cancelable: (type !== "mousemove"), 
 
        view: window, 
 
        detail: 0, 
 
        screenX: 0, 
 
        screenY: 0, 
 
        clientX: 1, 
 
        clientY: 1, 
 
        ctrlKey: false, 
 
        altKey: false, 
 
        shiftKey: false, 
 
        metaKey: false, 
 
        button: 0, 
 
        relatedTarget: undefined 
 
       }, options); 
 

 
       if (document.createEvent) { 
 
        event = document.createEvent("MouseEvents"); 
 
        event.initMouseEvent(type, options.bubbles, options.cancelable, 
 
         options.view, options.detail, 
 
         options.screenX, options.screenY, options.clientX, options.clientY, 
 
         options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, 
 
         options.button, options.relatedTarget || document.body.parentNode); 
 

 
        // IE 9+ creates events with pageX and pageY set to 0. 
 
        // Trying to modify the properties throws an error, 
 
        // so we define getters to return the correct values. 
 
        if (event.pageX === 0 && event.pageY === 0 && Object.defineProperty) { 
 
         eventDoc = event.relatedTarget.ownerDocument || document; 
 
         doc = eventDoc.documentElement; 
 
         body = eventDoc.body; 
 

 
         Object.defineProperty(event, "pageX", { 
 
          get: function() { 
 
           return options.clientX + 
 
            (doc && doc.scrollLeft || body && body.scrollLeft || 0) - 
 
            (doc && doc.clientLeft || body && body.clientLeft || 0); 
 
          } 
 
         }); 
 
         Object.defineProperty(event, "pageY", { 
 
          get: function() { 
 
           return options.clientY + 
 
            (doc && doc.scrollTop || body && body.scrollTop || 0) - 
 
            (doc && doc.clientTop || body && body.clientTop || 0); 
 
          } 
 
         }); 
 
        } 
 
       } else if (document.createEventObject) { 
 
        event = document.createEventObject(); 
 
        $.extend(event, options); 
 
        // standards event.button uses constants defined here: http://msdn.microsoft.com/en-us/library/ie/ff974877(v=vs.85).aspx 
 
        // old IE event.button uses constants defined here: http://msdn.microsoft.com/en-us/library/ie/ms533544(v=vs.85).aspx 
 
        // so we actually need to map the standard back to oldIE 
 
        event.button = { 
 
         0: 1, 
 
         1: 4, 
 
         2: 2 
 
        }[ event.button ] || (event.button === -1 ? 0 : event.button); 
 
       } 
 

 
       return event; 
 
      }, 
 

 
      keyEvent: function (type, options) { 
 
       var event; 
 
       options = $.extend({ 
 
        bubbles: true, 
 
        cancelable: true, 
 
        view: window, 
 
        ctrlKey: false, 
 
        altKey: false, 
 
        shiftKey: false, 
 
        metaKey: false, 
 
        keyCode: 0, 
 
        charCode: undefined 
 
       }, options); 
 

 
       if (document.createEvent) { 
 
        try { 
 
         event = document.createEvent("KeyEvents"); 
 
         event.initKeyEvent(type, options.bubbles, options.cancelable, options.view, 
 
          options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, 
 
          options.keyCode, options.charCode); 
 
         // initKeyEvent throws an exception in WebKit 
 
         // see: http://stackoverflow.com/questions/6406784/initkeyevent-keypress-only-works-in-firefox-need-a-cross-browser-solution 
 
         // and also https://bugs.webkit.org/show_bug.cgi?id=13368 
 
         // fall back to a generic event until we decide to implement initKeyboardEvent 
 
        } catch (err) { 
 
         event = document.createEvent("Events"); 
 
         event.initEvent(type, options.bubbles, options.cancelable); 
 
         $.extend(event, { 
 
          view: options.view, 
 
          ctrlKey: options.ctrlKey, 
 
          altKey: options.altKey, 
 
          shiftKey: options.shiftKey, 
 
          metaKey: options.metaKey, 
 
          keyCode: options.keyCode, 
 
          charCode: options.charCode 
 
         }); 
 
        } 
 
       } else if (document.createEventObject) { 
 
        event = document.createEventObject(); 
 
        $.extend(event, options); 
 
       } 
 

 
       if (!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()) || (({}).toString.call(window.opera) === "[object Opera]")) { 
 
        event.keyCode = (options.charCode > 0) ? options.charCode : options.keyCode; 
 
        event.charCode = undefined; 
 
       } 
 

 
       return event; 
 
      }, 
 

 
      dispatchEvent: function (elem, type, event) { 
 
       if (elem[ type ]) { 
 
        elem[ type ](); 
 
       } else if (elem.dispatchEvent) { 
 
        elem.dispatchEvent(event); 
 
       } else if (elem.fireEvent) { 
 
        elem.fireEvent("on" + type, event); 
 
       } 
 
      }, 
 

 
      simulateFocus: function() { 
 
       var focusinEvent, 
 
        triggered = false, 
 
        element = $(this.target); 
 

 
       function trigger() { 
 
        triggered = true; 
 
       } 
 

 
       element.bind("focus", trigger); 
 
       element[ 0 ].focus(); 
 

 
       if (!triggered) { 
 
        focusinEvent = $.Event("focusin"); 
 
        focusinEvent.preventDefault(); 
 
        element.trigger(focusinEvent); 
 
        element.triggerHandler("focus"); 
 
       } 
 
       element.unbind("focus", trigger); 
 
      }, 
 

 
      simulateBlur: function() { 
 
       var focusoutEvent, 
 
        triggered = false, 
 
        element = $(this.target); 
 

 
       function trigger() { 
 
        triggered = true; 
 
       } 
 

 
       element.bind("blur", trigger); 
 
       element[ 0 ].blur(); 
 

 
       // blur events are async in IE 
 
       setTimeout(function() { 
 
        // IE won't let the blur occur if the window is inactive 
 
        if (element[ 0 ].ownerDocument.activeElement === element[ 0 ]) { 
 
         element[ 0 ].ownerDocument.body.focus(); 
 
        } 
 

 
        // Firefox won't trigger events if the window is inactive 
 
        // IE doesn't trigger events if we had to manually focus the body 
 
        if (!triggered) { 
 
         focusoutEvent = $.Event("focusout"); 
 
         focusoutEvent.preventDefault(); 
 
         element.trigger(focusoutEvent); 
 
         element.triggerHandler("blur"); 
 
        } 
 
        element.unbind("blur", trigger); 
 
       }, 1); 
 
      } 
 
     }); 
 

 
     /** complex events **/ 
 
     function findCenter(elem) { 
 
      var offset, 
 
       document = $(elem.ownerDocument); 
 
      elem = $(elem); 
 
      offset = elem.offset(); 
 

 
      return { 
 
       x: offset.left + elem.outerWidth()/2 - document.scrollLeft(), 
 
       y: offset.top + elem.outerHeight()/2 - document.scrollTop() 
 
      }; 
 
     } 
 

 
     function findCorner(elem) { 
 
      var offset, 
 
       document = $(elem.ownerDocument); 
 
      elem = $(elem); 
 
      offset = elem.offset(); 
 

 
      return { 
 
       x: offset.left - document.scrollLeft(), 
 
       y: offset.top - document.scrollTop() 
 
      }; 
 
     } 
 

 
     $.extend($.simulate.prototype, { 
 
      simulateDrag: function() { 
 
       var i = 0, 
 
        target = this.target, 
 
        options = this.options, 
 
        center = options.handle === "corner" ? findCorner(target) : findCenter(target), 
 
        x = Math.floor(center.x), 
 
        y = Math.floor(center.y), 
 
        coord = { clientX: x, clientY: y }, 
 
        dx = options.dx || (options.x !== undefined ? options.x - x : 0), 
 
        dy = options.dy || (options.y !== undefined ? options.y - y : 0), 
 
        moves = options.moves || 3; 
 

 
       this.simulateEvent(target, "mousedown", coord); 
 

 
       for (; i < moves; i++) { 
 
        x += dx/moves; 
 
        y += dy/moves; 
 

 
        coord = { 
 
         clientX: Math.round(x), 
 
         clientY: Math.round(y) 
 
        }; 
 

 
        this.simulateEvent(target.ownerDocument, "mousemove", coord); 
 
       } 
 

 
       if ($.contains(document, target)) { 
 
        this.simulateEvent(target, "mouseup", coord); 
 
        this.simulateEvent(target, "click", coord); 
 
       } else { 
 
        this.simulateEvent(document, "mouseup", coord); 
 
       } 
 
      } 
 
     }); 
 

 
    })($); 
 

 
    try { 
 
     var dragEle = $(dragEleSelector); 
 
     var dropEle = $(dropEleSelector); 
 
     if (dragEle.length == 0 || dropEle.length == 0) { 
 
      console.error("Unable to perform drag n drop operation: Selectors are incorrect."); 
 
      return false; 
 
     } 
 
     var droppableOffset = dropEle.offset(), 
 
      draggableOffset = dragEle.offset(), 
 
      dx = droppableOffset.left - draggableOffset.left, 
 
      dy = droppableOffset.top - draggableOffset.top; 
 

 
     dragEle.simulate("drag", { 
 
      dx: dx, 
 
      dy: dy 
 
     }); 
 
     return true; 
 
    } catch (err) { 
 
     console.error("Unable to perform drag n drop operation."); 
 
     return false; 
 
    } 
 
};

代码您必须对由CSS选择器指定的DOM元素执行这个脚本。

var dragDrop = require('../../common/javascript/dragDrop.js'); 
 

 
//keep this in mind selectors are CSS selectors. 
 
function dragDropElement(dragEleSelector, dropEleSelector) { 
 
    var deferred = protractor.promise.defer(); 
 
    browser.executeScript(dragDrop, dragEleSelector, dropEleSelector).then(function (dropSuccessful) { 
 
     expect(dropSuccessful).toBe(true); 
 
     if (dropSuccessful) { 
 
      console.log("Element dropped successfully on target."); 
 
      deferred.fulfill(dropSuccessful); 
 
     } else { 
 
      console.log("Fail: Not able to drop element on target."); 
 
      deferred.reject(dropSuccessful); 
 
     } 
 
    }); 
 
    return deferred.promise; 
 
};

虽然你将无法看到拖放动画,但它会奏效。

0

我有各种各样的dnd模拟库的问题,似乎不能使用角拖拖放列表。

最后我分叉了html-dnd只是简单地添加一个dragover事件,一些角拖 - 拖放列表需要,因为它通过dragover事件计算被放置的元素的索引。它也粘在一个临时li元素中,代码在删除它之前将其用作实际放置点。这是用户在屏幕上看到的移动列表点。

叉在forked html-dnd。我包括它通过在依赖关系混帐拉在我的package.json文件

"html-dnd": "git://github.com/PloughingAByteField/html-dnd.git" 

对于使用在量角器

// at the top of the spec 
var dragAndDrop = require('html-dnd').code; 

<snip> 

it('should dragover and drop', function() { 
    var draggable = browser.findElement(by.id('id1')); 
    var droppable = browser.findElement(by.id('id2')); 
    browser.driver.executeScript(dragAndDrop, draggable, droppable); 
); 

更新: 的HTML-DND项目在dragover事件已经合并,使你可以使用,而不是我没有维护的叉子。