Including external script in Angular Protractor test that requires parameters to be passed in

主宰稳场 提交于 2020-04-18 05:50:26

问题


I would like to include the following script in my Angular protractor test:

// Originally from https://ghostinspector.com/blog/simulate-drag-and-drop-javascript-casperjs/
// trimmed down and modified by @kemokid (Martin Baker) to work with Sortable.js
///
// Probably not going to work with dragging from one list to another

// Call with DOM selectors, eg `triggerSortableDragAndDrop('#drag', '#drop');`

// Returns false if unable to start.
// callback, if present, will be called with true if able to finish, false if not.
// If you receive "false" on the callback, the list is likely not in the beginning state.
var triggerSortableDragAndDrop = function (selectorDrag, selectorDrop, callback) {
  var DELAY_INTERVAL_MS = 10;
  var MAX_TRIES = 10;

  // fetch target elements
  var elemDrag = document.querySelector(selectorDrag);
  var elemDrop = document.querySelector(selectorDrop);

  if (!elemDrag || !elemDrop) {
    console.log("can't get elements");
    return false;
  }

  var startingDropRect = elemDrop.getBoundingClientRect();

  function rectsEqual(r1, r2) {
    return r1.top === r2.top && r1.right === r2.right && r1.bottom === r2.bottom && r1.left === r2.left;
  }

  // function for triggering mouse events
  function fireMouseEvent(type, elem) {
    var evt = document.createEvent('MouseEvents');
    evt.initMouseEvent(type, true, true, window, 1, 1, 1, 0, 0, false, false, false, false, 0, elem);
    elem.dispatchEvent(evt);
  };

  // trigger dragging process on top of drop target
  // We sometimes need to do this multiple times due to the vagaries of
  // how Sortable manages the list re-arrangement
  var counter = 0;
  function dragover() {
    counter++;
    console.log('DRAGOVER #' + counter);

    var currentDropRect = elemDrop.getBoundingClientRect();
    if (rectsEqual(startingDropRect, currentDropRect) && counter < MAX_TRIES) {
      if (counter != 1) console.log("drop target rect hasn't changed, trying again");

      // mouseover / mouseout etc events not necessary
      // dragenter / dragleave events not necessary either
      fireMouseEvent('dragover', elemDrop);

      setTimeout(dragover, DELAY_INTERVAL_MS);
    } else {
      if (rectsEqual(startingDropRect, currentDropRect)) {
        console.log("wasn't able to budge drop target after " + MAX_TRIES + " tries, aborting");
        fireMouseEvent('drop', elemDrop);
        if (callback) callback(false);
        } else {
        setTimeout(drop, DELAY_INTERVAL_MS);
        }
    }
  }

  function drop() {
    console.log('DROP');
    // release dragged element on top of drop target
    fireMouseEvent('drop', elemDrop);
    fireMouseEvent('mouseup', elemDrop);    // not strictly necessary but I like the symmetry
    if (callback) callback(true);
  }

  // start dragging process
  console.log('DRAGSTART');
  fireMouseEvent('mousedown', elemDrag);
  fireMouseEvent('dragstart', elemDrag);

  // after a delay, do the first dragover; this will run up to MAX_TRIES times
  // (with a delay between each run) and finally run drop() with a delay:
  setTimeout(dragover, DELAY_INTERVAL_MS);
  return true;
};

and call it as follows: triggerSortableDragAndDrop(fromItemId, toItemId). Is this possible?

I was thinking of doing it this way:

  static sortableDragAndDropByClassName(dragElementClassName: string, dropElementClassName: string) {
    const CUSTOM_JS_SCRIPT = 'var triggerSortableDragAndDrop=function(t,e,o){var n=10,r=10,g=document.querySelector(t),a=document.querySelector(e);if(!g||!a)return console.log("can't get elements"),!1;var i=a.getBoundingClientRect();function u(t,e){return t.top===e.top&&t.right===e.right&&t.bottom===e.bottom&&t.left===e.left}function c(t,e){var o=document.createEvent("MouseEvents");o.initMouseEvent(t,!0,!0,window,1,1,1,0,0,!1,!1,!1,!1,0,e),e.dispatchEvent(o)}var l=0;function s(){console.log("DROP"),c("drop",a),c("mouseup",a),o&&o(!0)}return console.log("DRAGSTART"),c("mousedown",g),c("dragstart",g),setTimeout(function t(){l++,console.log("DRAGOVER #"+l);var e=a.getBoundingClientRect();u(i,e)&&l<r?(1!=l&&console.log("drop target rect hasn't changed, trying again"),c("dragover",a),setTimeout(t,n)):u(i,e)?(console.log("wasn't able to budge drop target after "+r+" tries, aborting"),c("drop",a),o&&o(!1)):setTimeout(s,n)},n),!0};';
    const dragElement = element(by.className(dragElementClassName));
    const dropElement = element(by.className(dropElementClassName));
    // parameters don't get passed
    return browser.executeScript(CUSTOM_JS_SCRIPT, dragElement.getWebElement(), dropElement.getWebElement());
  }

But I can't seem to figure out a way to pass in the two parameters the original script asks for.


回答1:


Simple way to perform drag and drop operation.

Use html-dnd NPM module.

Link:https://www.npmjs.com/package/html-dnd

code snippet:

var dragAndDrop = require('html-dnd').code;

var draggable = driver.findElement(By.id('draggable'));

var droppable = driver.findElement(By.id('droppable'));

driver.executeScript(dragAndDrop, draggable, droppable);


来源:https://stackoverflow.com/questions/61226704/including-external-script-in-angular-protractor-test-that-requires-parameters-to

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!