navi
navi

Reputation: 193

Cypress submitting form with preventDefault

I am having trouble using Cypress.

There are 2 problems I'm currently having.

  1. A form with preventDefault is being submitted and the page is refreshing.
  2. I have to .click() and input before I can .type() into it.

--

I have a form that has preventDefault, and you can see from the test that it submites the form, which adds a empty query string to the url, and none of my error handling messages are shown. This doesn't actually happen when I use the app myself.

    it('requires email', () => {
        cy.visit('/sign-in')
        cy.get('form').contains('Sign in').click()
        cy.get('.errors').should('contain', 'Email is required.')
    })

I am using Svelte/Sapper as my front-end.

enter image description here

Form:

<form on:submit|preventDefault={handleSubmit}>
    <Input label="Email" type="email" bind:value={email} />
    <Input label="Password" type="password" bind:value={password} />
    <Button text="Sign in" />
</form>

The second issue is that I have to .click() and input in my test before I can .type() into it.

I have to do this:

cy.get('#email').click().type('[email protected]{enter}')

Instead of this:

cy.get('#email').type('[email protected]{enter}')

I am not sure why this is happening. If I don't click the field, it says the field may have the attribute disabled, which it doesn't. When I test it myself, I don't see any issues, and the dom snapshots in Cypress don't reveal anything unusual.

Perhaps it has to do with autofill?

Has anyone run into these problems?

Upvotes: 0

Views: 2623

Answers (1)

navi
navi

Reputation: 193

The issue with Sapper is that it is SSR, so the app was not hydrated before Cypress started running tests, which was causing a whole bunch of issues.

The solution was to tell Cypress to wait until the app was hydrated. This was accomplished by setting an attribute in the return to the promise from sapper.start and then overwriting the Cypress visit command.

client.js:

sapper.start({
    target: document.querySelector("#app"),
}).then(() => {
    document.body.setAttribute('hydrated', '')
})

Cypress commands:

Cypress.Commands.overwrite('visit', (orig, url, options) => {
    orig(url, options)
    cy.get('body[hydrated]').should('have.length', 1)
})

Now everything works and tests are passing.

Upvotes: 1

Related Questions