Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cypress: same tests that pass in browser fail in headless mode due to timeout

When I run Cypress with vue-cli-service test:e2e --headless some tests inside a register request callback fail:

enter image description here

whereas normally when run in browser (vue-cli-service test:e2e) they pass:

enter image description here

 it('Submit WITHOUT promo code', () => {
        cy.server();
        cy.route({method: 'POST', url: 'api/register'}).as('register');

        cy.get('.thz-items-loading').should('not.be.visible');
        cy.get('#btn-submit').should('not.be.disabled');

        cy.get('iframe[name^="__privateStripeFrame"]').then(($iframe) => {
            const $body = $iframe.contents().find('body');

            cy.wrap($body).find('input:eq(1)').click({force: true}).clear();
            cy.wrap($body).find('input:eq(1)').type('4000000000009979'); // stolen card
            cy.get('#btn-submit').click(); // SUBMIT FORM

            cy.wait('@register').then(xhr => {
                cy.contains('#card-errors', 'Your card was declined.');
                // cy.get('.thz-items-loading').should('not.be.visible'); // FAILS
                // cy.get('.thz-items-loading').to.have.style('display', 'none'); // FAILS
                cy.get('#btn-submit').should('not.be.disabled'); // FAILS
                (...)
            });

            return null;
        });
(...)

Stack trace:

1) Trial registration form Submit WITHOUT promo code: CypressError: Timed out retrying: expected <button#btn-submit.thz-button.thz-radius-50.thz-btn-border-2.thz-align-center.thz-ff-g-hind-vadodara-600> not to be 'disabled' at Object.cypressErr (https://localhost:8000/__cypress/runner/cypress_runner.js:82944:11) at Object.throwErr (https://localhost:8000/__cypress/runner/cypress_runner.js:82909:18) at Object.throwErrByPath (https://localhost:8000/__cypress/runner/cypress_runner.js:82936:17) at retry (https://localhost:8000/__cypress/runner/cypress_runner.js:76454:16) at https://localhost:8000/__cypress/runner/cypress_runner.js:68529:18 at tryCatcher (https://localhost:8000/__cypress/runner/cypress_runner.js:131381:23) at Promise._settlePromiseFromHandler (https://localhost:8000/__cypress/runner/cypress_runner.js:129399:31) at Promise._settlePromise (https://localhost:8000/__cypress/runner/cypress_runner.js:129456:18) at Promise._settlePromise0 (https://localhost:8000/__cypress/runner/cypress_runner.js:129501:10) at Promise._settlePromises (https://localhost:8000/__cypress/runner/cypress_runner.js:129576:18) at Async._drainQueue (https://localhost:8000/__cypress/runner/cypress_runner.js:126305:16) at Async._drainQueues (https://localhost:8000/__cypress/runner/cypress_runner.js:126315:10) at Async.drainQueues (https://localhost:8000/__cypress/runner/cypress_runner.js:126189:14) at

Following lines inside cy.wait('@register') callback should pass in headless mode:

cy.get('.thz-items-loading').should('not.be.visible');
cy.get('.thz-items-loading').to.have.style('display', 'none');
cy.get('#btn-submit').should('not.be.disabled');

Looks like the timeout happens because elements #btn-submit and .thz-items-loading are not reachable in @register callback, even though in both cases they exist in DOM, but why? They are reachable before the request just fine.

I'm running Cypress 3.2.0 from a project created with vue-cli on Windows 10. Tested app is not a part of the project, is hosted elsewhere and is a static html page. Headless browser is Electron 59.

like image 673
van_folmert Avatar asked Mar 21 '19 12:03

van_folmert


1 Answers

It turns out that Electron browser silently fails at executing newer syntax like Promises, that's why code in resolved Promise's then() callback which was supposed to change display property of .thz-items-loading and #btn-submit was never executed and tests expecting that change never passed.

Adding babel's polyfills before main.js of tested APP fixed this issue:

<script src="../../node_modules/@babel/polyfill/dist/polyfill.min.js"></script> <!-- or copy to root dir in build process -->
<script src="./main.js"></script>
like image 149
van_folmert Avatar answered Oct 13 '22 00:10

van_folmert