Search code examples
d3.jscypress

Moving d3 objects in a Cypress test


I'm testing a d3 app which uses <svg> to draw items on the screen. I have event handlers dragstarted, dragged and dragend and also some .force() calls to add some physics to the simulation.

  function dragstarted(d) {
    if (!d3.event.active) simulation.alphaTarget(.03).restart();
    d.fx = d.x;
    d.fy = d.y;
  }
  function dragged(d) {
    d.fx = d3.event.x;
    d.fy = d3.event.y;
  }
  function dragended(d) {
    if (!d3.event.active) simulation.alphaTarget(.03);
    d.fx = null;
    d.fy = null;
  }

  var simulation = d3.forceSimulation()
      .force("center", d3.forceCenter().x(width / 2).y(height / 2))
      .force("charge", d3.forceManyBody().strength(1))
      .force("collide", d3.forceCollide().strength(.1).radius(30).iterations(1)) 
  
  simulation
      .nodes(data)
      .on("tick", function(d){
        node
            .attr("cx", function(d){ return d.x; })
            .attr("cy", function(d){ return d.y; })
      });
  

The objects move when dragged by user, but the test does not replicate the process

  cy.get(selector).eq(0)
    .trigger('mousedown', { which: 1, force: true, view: window })
    .trigger('mousemove', {clientX: 300, clientY: 500, force: true})
    .trigger('mouseup', {position: 'top', force: true})

What am I doing wrong? Are the force methods interfering with the test (due to time-lag in settling the movement)?


Solution

  • You have a reference to window in the event trigger, but this refers to the test runner window and not the window of AUT (application under test).

    Try fetching the AUT window and running the code in the callback

    cy.window().then(window => {
      cy.get(selector).eq(0)
        .trigger('mousedown', { which: 1, force: true, view: window })
        .trigger('mousemove', {clientX: 300, clientY: 500, force: true})
        .trigger('mouseup', {position: 'top', force: true})
    })