在Cypress中测试拖动传单地图

2022-03-13 00:00:00 leaflet dom javascript cypress

我有一个非常简单的用例:我希望在更改传单地图视口时通过抓取它来测试数据获取。然而,我不知道如何写这个测试。 代码如下:

      cy.visit("/map");
      // wait for data
      cy.get(".leaflet-interactive.multilinestring");
      // simulate map moving
      cy.get(".leaflet-container")
        .trigger("mousedown", "center")
        .trigger("mousemove", 30, 30);
        .trigger("mouseup");
      // map should be loading
      cy.get(".leaflet-container.leaflet-loading");

它似乎没有移动地图。

我已尝试在触发器调用之间添加等待,因为我认为可能有关于事件激发速度的警卫,但没有运气。

是否知道如何测试此功能。


解决方案

似乎不使用cy.trigger(),而是需要使用本机事件使传单认为地图正在拖动。

我们编写了一个自定义的Cypress命令dragMapFromCenter,使用它如下所示:

cy.get('#map-canvas').dragMapFromCenter({
  // Go 1/6 of map container width to the right (negative direction)
  xMoveFactor: -1 / 6,
  // Go 1/3 of map container height to the top (positive direction)
  yMoveFactor: 1 / 3
});

// We need to wait for something to happen after map starts moving
cy.get(".leaflet-container.leaflet-loading");

下面是dragMapFromCenter的实现。将其放入cypress/support/commands.js以便能够在测试中使用。

// # cy.get('#map-canvas').dragMapFromCenter({ xMoveFactor: 0.25, yMoveFactor: -0.5 })
//
// Allows dragging a Leaflet map by the given amounts. A factor of 1 means the map
// will be dragged the whole width of the map canvas in X direction and the whole
// height of the map canvas in Y direction.
Cypress.Commands.add(
  'dragMapFromCenter',
  { prevSubject: 'element' },
  (element, { xMoveFactor, yMoveFactor }) => {
    // Get the raw HTML element from jQuery wrapper
    const canvas = element.get(0);
    const rect = canvas.getBoundingClientRect();
    const center = {
      x: rect.left + rect.width / 2,
      y: rect.top + rect.height / 2
    };

    // Start dragging from the center of the map
    cy.log('mousedown', {
      clientX: center.x,
      clientY: center.y
    });
    canvas.dispatchEvent(
      new MouseEvent('mousedown', {
        clientX: center.x,
        clientY: center.y
      })
    );

    // Let Leaflet know the mouse has started to move. The diff between
    // mousedown and mousemove event needs to be large enough so that Leaflet
    // will really think the mouse is moving and not that it was a click where
    // the mouse moved just a tiny amount.
    cy.log('mousemove', {
      clientX: center.x,
      clientY: center.y + 5
    });
    canvas.dispatchEvent(
      new MouseEvent('mousemove', {
        clientX: center.x,
        clientY: center.y + 5,
        bubbles: true
      })
    );

    // After Leaflet knows mouse is moving, we move the mouse as depicted by the options.
    cy.log('mousemove', {
      clientX: center.x + rect.width * xMoveFactor,
      clientY: center.y + rect.height * yMoveFactor
    });
    canvas.dispatchEvent(
      new MouseEvent('mousemove', {
        clientX: center.x + rect.width * xMoveFactor,
        clientY: center.y + rect.height * yMoveFactor,
        bubbles: true
      })
    );

    // Now when we "release" the mouse, Leaflet will fire a "dragend" event and
    // the search should register that the drag has stopped and run callbacks.
    cy.log('mouseup', {
      clientX: center.x + rect.width * xMoveFactor,
      clientY: center.y + rect.height * yMoveFactor
    });
    requestAnimationFrame(() => {
      canvas.dispatchEvent(
        new MouseEvent('mouseup', {
          clientX: center.x + rect.width * xMoveFactor,
          clientY: center.y + rect.height * yMoveFactor,
          bubbles: true
        })
      );
    });
  }
);

相关文章