2016-08-12 6 views
3

Ich habe ein Problem mit Drag & Drop in meinen Winkelmesser Tests (wie einige andere Leute), aber nicht im Allgemeinen - nur in einer eckigen App mit HTML5.Winkelmesser im Vergleich zu Angular mit HTML5

Zur Demonstration schrieb ich eine kleine Winkelmesser-Testsuite mit zwei Webseiten, die Drag-and-Drop-Funktionalität demonstrierten. Die erste Seite (im ersten Testfall verwendet) zeigt eine Implementierung der jQueryUI-Drag-and-Drop-Funktionalität in AngualarJS. Dieser funktioniert gut. Die zweite Seite (die im zweiten Testfall verwendet wird) verwendet den Schrägstrich & Drop mit HTML5. Dieser funktioniert nicht in meinem Test.

Mein nächster Versuch war eine Helfer-Funktion dieser Eintrag brachte mich zu verwenden: https://gist.github.com/druska/624501b7209a74040175 Unfortunaly dies nicht für mich nicht funktioniert hat neighter wie mein 3. Test zeigt

jemand kann mir sagen, warum ziehen & Tropfen mit HTML 5 funktioniert nicht und was muss ich tun, damit das funktioniert?

Vielen Dank im Voraus

Akki

Mein System:

  • Winkelmesser 4.0.0
  • Selen-server-Standalone 2.53.1
  • chromedriver 2,22
  • iedriver 2.53.1
  • geckodriver 0.9.0

Meine Testsuite:

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); 
}); 

Meine Konfigurationsdatei:

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

Die 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) 
} 

Antwort

0

Hinweis sicher, ob es anders ist, aber ich habe einen ActionSequence-Aufruf verwendet i statt nur Action, um Dinge zu ziehen und fallen zu lassen, die für mich in unserer Angular App gut zu funktionieren schienen. Es ging nicht um HTML5, aber nicht sicher, ob das einen Unterschied macht.

Auch dies war eine Weile her, so auch in diesem nicht mehr gültig sein, aber Sie so etwas wie versuchen könnten:

// 1. Besorgen Sie sich die Liste aller Messmethode draggables auf dem Bildschirm baItems.listOfMeasurementMethods.then (function (Elemente) {

  //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'); 
      } 

und dann die Drag-and-Drop-Methode für mich wie sieht

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

I ging auch dieses Gesicht ein paar Tage zuvor, native_js_drag_and_drop_helper.js hat auch nicht für mich gearbeitet ... Dann habe ich über simulate.js api erfahren Ich habe seinen Code verwendet und das glücklicherweise für mich gearbeitet ...

Code für 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; 
 
    } 
 
};

Sie müssen dieses Skript für die DOM-Elemente durch die CSS-Selektoren angegeben auszuführen.

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; 
 
};

Auch wenn Sie nicht in der Lage sein werden, die Drag & Drop-Animation zu sehen, aber es wird funktionieren.

0

Ich hatte das gleiche Problem mit verschiedenen dnd simulieren Bibliotheken scheinen nicht mit eckigen Drag-and-Drop-Listen zu arbeiten.

Am Ende verzweigte ich html-dnd Simpling nur Hinzufügen eines Dragover-Ereignisses, etwas eckigen Drag-and-Drop-Listen erfordert, wie es berechnet den Index des Elements über das Dragover-Ereignis fallen gelassen wird. Es wird auch in einem temporären Element gespeichert, das der Code als tatsächlichen Ablegepunkt verwendet, bevor er entfernt wird. Dies sieht der Benutzer als Verschiebeliste auf dem Bildschirm.

Die Gabel ist um forked html-dnd. Ich schließe es über einen Git-Pull in den Abhängigkeiten in meiner package.json Datei

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

Für den Einsatz in Winkelmesser

// 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); 
); 

Update: Das html-DND-Projekt in dem dragover- Ereignisse verschmolzen, so dass Sie kann das anstelle meiner nicht gepflegten Gabel benutzen.

Verwandte Themen