Flaky snapshots with Percy and Cypress when animating

493 Views Asked by At

I’m adding a couple of animations to an app that has Percy taking snapshots in the cypress tests.

I’m trying to figure out a way to wait for the animations to finish before taking the snapshot.

I’m aware that cypress already does that by default according to the docs. But it seems that it only waits until the element is safe for an ACTION, but not regular assertions.

Let’s use my logo animation for example. It slides from the left to center. The flaky tests capture the snapshot anywhere in its path.

Now, just for a test, I asked cypress to click the logo and then Percy works alright, the snapshot is only taken at the end of the animation.

For this case it’s ok, since my logo does not have an action related to it. But what if clicking it had a redirect, for example?

How can I tell cypress to wait without using an action?

1

There are 1 best solutions below

1
On

Can you assert the slide has finished before the snapshot?

It would involve a element.getBoundingClientRect() and manually checking the position.

it('waits for logo to slide to center', 
  {viewportWidth: 1000},    // ensure fixed, appropriate viewport for the test
  () => {
    cy.get('#myLogo')
      .should($logo => {    // using should will retry until animation finishes

        const left = $logo[0].getBoundingClientRect().left
        expect(left).to.eq(450)
      })
    // snapshot now
  }
)

I'm doing this with a drag and drop scenario, but finding the numbers have rounding errors.

I've added chai-almost to sort it out.

const chaiAlmost = require('chai-almost')
chai.use(chaiAlmost(1))        // allowed amount of variance in equality is 1

...

expect(left).to.almost.eq(450)

Simplest way is to add a hard cy.wait(animation-time-in-ms) before the snapshot.

It won't make the difference to the test runtime since you need the animation to finish before the test can complete.