Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Create most complex test cases for e2e #21

Open
bharathmuppa opened this issue Aug 1, 2024 · 5 comments
Open

Create most complex test cases for e2e #21

bharathmuppa opened this issue Aug 1, 2024 · 5 comments

Comments

@bharathmuppa
Copy link

Current e2e has basic tests like checking size of nodes and edges and so on, but it would be really nice to cover more test's like

  1. Creating edge between two nodes, track the path.
  2. Creating edge from outgoing node ports to incoming ports of other node.
  3. Creating Test for checking edge path for bends.
  4. Checking label location after creation in case of manual label creation.
@bharathmuppa
Copy link
Author

We are working mostly with playwright and cypress, so I would prefer to see those

@yGuy
Copy link
Member

yGuy commented Aug 1, 2024

The demos are meant to be instructive and show how to do things conceptually.
The testing demos are in no way meant to be tests that provide a good coverage over yFiles features.
We have tons of tests internally which do things like the tests you mentioned above. But there are no plans to and I don't see a good reason for adding them to the demos. I also don't really see what good it would be for customers to test the core yFiles functionality if we already do it extensively.

Do you see any conceptual problem with the current demo code? Is there a yFiles specific concept missing that we should cover?

@thomasbehr
Copy link
Member

@bharathmuppa While I agree with Sebastian, I would like to add that both Playwright and Cypress offer the possibility to execute almost arbitrary JavaScript code within the context of the page that is being tested.

In Playwright, you can use Page.evaluate towards this end. E.g. the following example shows how you can create an edge in a test case (see line 28):

test('Test yFiles', async ({ page }) => {
  await page.goto('/demos-ts/testing/application-under-test/index.html')
  await page.locator('.loaded').waitFor()

  const result1 = await await page.evaluate(() => {
    yfilesDebug()
    const graphComponent = window.yfiles.CanvasComponent.getComponent(
      document.getElementById('graphComponent')
    )
    const graph = graphComponent.graph
    return {
      edgeCount: graph.edges.size,
      nodeCount: graph.nodes.size
    }
  })

  await expect(result1).toBeTruthy()
  await expect(result1.nodeCount).toBe(2)
  await expect(result1.edgeCount).toBe(0)

  const result2 = await await page.evaluate(() => {
    yfilesDebug()
    const graphComponent = window.yfiles.CanvasComponent.getComponent(
      document.getElementById('graphComponent')
    )
    const graph = graphComponent.graph

    graph.createEdge(graph.nodes.first(), graph.nodes.last())

    return {
      edgeCount: graph.edges.size,
      nodeCount: graph.nodes.size
    }
  })

  await expect(result2).toBeTruthy()
  await expect(result2.nodeCount).toBe(2)
  await expect(result2.edgeCount).toBe(1)
})

The above example assumes the setup of yFiles' Playwright testing demo, i.e. the test is run against yFiles' application-under-test sample application (which starts with two initial nodes).

For Cypress testing this should be even easier, as yFiles' Cypress testing demo already runs JavaScript inside the context of the page being tested. E.g. the following example shows how you can create a node label in a test case (see line 19):

describe('yfiles spec', () => {
  it('should increase edge count by 1', () => {
    /**
     * We assume that the yFiles demo server is running.
     * If not, please start it with the appropriate script or change
     * the URL below to an application you would like to test.
     */
    cy.visit('http://localhost:4242/demos-ts/testing/application-under-test/index.html').then(() => {
      cy.get('.loaded').should('exist')
      cy.window().then((win) => {
        // win is the remote window
        const graphComponent = (win as Cypress.AUTWindow & { graphComponent: GraphComponent })
          .graphComponent
        if (!graphComponent) {
          throw new Error('graphComponent is undefined')
        }

        const graph = graphComponent.graph
        const label = graph.addLabel(graph.nodes.first(), "Test")
        const labelBounds = label.layout.bounds
        expect(labelBounds.width).to.be.greaterThan(0)

        const startEdges = graphComponent.graph.edges.size

        cy.get('button[id="create-edge"]')
          .click()
          .then(() => {
            const endEdges = graphComponent.graph.edges.size
            if (endEdges !== startEdges + 1) {
              throw new Error(`number of edges after creating a new one is wrong: ${endEdges}.`)
            }
          })
      })
    })
  })
})

The above example assumes the setup of yFiles' Cypress testing demo.

Hope this helps.

@bharathmuppa
Copy link
Author

I know it make lots of sense for developers especially for component testing, but e2e intended mostly for testers within our team and they don't know much about yfiles internals, what they try to do is simulate user flow like below

Use case : create 2 nodes and draw a relation

  • Open page
  • Click on some location of viewport which is actually on graph
  • Popups some dialog where they enter node information
  • Assert location of saved node, size and its data within svg found by locators.
  • Repeat to create other node
  • Drag mouse from source node port to other node via some path and drop it on target node port
  • assert the path created like checking bend locations.

I can be in your shoes and see this should be done by teams, but it would be great for them to have a reference guide for complex scenario and then they can build more complex interactions on there own.

@yGuy
Copy link
Member

yGuy commented Aug 7, 2024

That's a weird mix of an e2e test, IMHO where the test is ultimately interpreting the SVG DOM to check whether a business logic was performed correctly. I would recommend checking the data instead or if you don't want this, use screenshot testing, rather than interpreting SVG values, where you will probably end up having to change and augment the SVG just to make it "testable". We've seen this before and there are typically more errors introduced in the code-base just because of this "make the DOM fully inspectable from outside and self-explanatory" than are avoided by the tests. It also slows down the user agent and increased DOM and code size.

So, I don't really buy the argument about testers not having to know any details with the proposed approach. With that approach they would need to understand the low-level details of the SVG DOM that not even the devs are typically aware of. The SVG DOM is an implementation detail for many of the default styles. So why not use image-based testing, instead and avoid all these problems?

That being said, we do have some UI automation and testing examples that show how to do this super-low-level UI testing programmatically.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants