简体   繁体   English

使用赛普拉斯在SVG上测试onclick事件

[英]Testing onclick events on SVG with Cypress

I am testing a d3 application with Cypress. 我正在测试赛普拉斯的d3应用程序。 As of the tests, I'd like to make sure a specific function is called when a circle within an SVG element is clicked. 在测试中,我想确保在单击SVG元素中的圆时调用特定函数。 The function is called when I'm clicking manually but the test that I wrote fails, so I assume I made a mistake somewhere in the test. 当我手动点击但是我写的测试失败时调用该函数,所以我假设我在测试的某个地方犯了一个错误。 Here's the test code I have right now: 这是我现在的测试代码:

import * as app from "../../app";

describe("Scatter plot", () => {
  before(() => {
    cy.visit("http://localhost:1234");
  });
  it("Triggers the displayMovieInfo on click", () => {
    const displayMovieInfo = cy.spy(app, "displayMovieInfo");
    cy.get("#scatterPlot")
      .get("circle")
      .eq(0)
      .click({ force: true });

    expect(displayMovieInfo).to.be.called;
  });
});

The output I get from Cypress: 我从赛普拉斯得到的输出:

expected displayMovieInfo to have been called at least once, but it was never called 预期displayMovieInfo至少被调用一次,但从未调用过

Any help will be appreciated! 任何帮助将不胜感激!

Update: I believe the click might have not worked before because the circle didn't exist when cypress attempted to click it. 更新:我认为点击可能之前没有用,因为当cypress试图点击它时,圆圈不存在。 By adding "await cy.wait(1000);" 添加“await cy.wait(1000);” before the click action, the function is called (I can see the results and a message logged from inside it). 在单击操作之前,调用该函数(我可以看到结果并从其中记录消息)。 Sadly, the test is still failing. 可悲的是,测试仍然失败。

Update 2: I changed the test to use the window object (see below), but the assertion still fails (the test itself succeeds, which is also not a good thing). 更新2:我改变了测试以使用窗口对象(见下文),但断言仍然失败(测试本身成功,这也不是一件好事)。

 cy.window()
      .then(window => {
        displayMovieInfoSpy = cy.spy(window, "displayMovieInfo");
        cy.get("#scatterPlot")
          .get("circle")
          .eq(2)
          .click({ force: true })
          .as("clicking");
        expect(displayMovieInfoSpy).to.be.called;
      });

Update 3: It seems that the combination of d3 and parcel.js causes the test to fail. 更新3:似乎d3和parcel.js的组合导致测试失败。 When using d3 alone or parcel.js alone, the test works just fine. 单独使用d3或单独使用parcel.js时,测试工作正常。 Also, the expect statement should be in the then block after the click action. 此外,expect语句应该在click操作之后的then块中。

Seems you're importing app variable on the test directly. 似乎您直接在测试中导入app变量。 This object is a different one than the one on your browser. 此对象与浏览器上的对象不同。 You should make a global variable (or method) for getting your app variable directly from your browser 您应该创建一个全局变量(或方法),以便直接从浏览器获取您的app变量

cy.window().its('app').then((app) => { 
   // your test with app var
})

Also you might want to use then() condition to ensure it checks it after. 此外,您可能希望使用then()条件以确保它在之后进行检查。 But this may not be necessary. 但这可能没有必要。

.click({ force: true }).then(() => {
   expect(displayMovieInfo).to.be.called;
});

I think you have mostly a couple concept problems about how cypress is working. 我认为你对柏树的工作方式大多有几个概念问题。

First click only can be on one element and second is about how you use alias. 第一次单击只能在一个元素上,第二次是关于如何使用别名。

This code I put works like a charm, hope it helps you a little about the concepts of alias, should, click and spy. 这段代码我的作品就像一个魅力,希望它能帮助你一点点别名的概念,点击和间谍。

d3test.spec.js d3test.spec.js

describe("Scatter plot", () => {
before(() => {
  cy.visit("http://localhost/d3test");
});
it("Triggers the displayMovieInfo on click", () => {
    cy.window()
    .then(window => {
      let displayMovieInfoSpy = cy.spy(window, "displayMovieInfo");

      cy.get("#scatterPlot").get("circle").as('circles')

      cy.get('@circles').should('have.length', 1)

      cy.get('@circles').click({ force: true })
        .then(() => {
            expect(displayMovieInfoSpy).to.be.called;
        })
    });
});
});

index.html 的index.html

<svg id="scatterPlot">
    <circle cx="50%" cy="50%" r="100" fill="blue" onclick="displayMovieInfo()"></circle>
</svg>
<script src="https://d3js.org/d3.v5.min.js"></script>
<script>
    window.displayMovieInfo = function(){
        console.log(1);
    }
</script>

If you have more troubles I recomend you trying stuff one by one, using cy.log() and debugger console. 如果你有更多的麻烦我建议你逐个尝试使用cy.log()和调试器控制台。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM