Estoy intentando crear algunas pruebas básicas para probar la nueva biblioteca Cypress. En mi prueba tengo cy.visit('http://mywebsite.com'); que está cargando una aplicación AngularJS que usa SystemJS.

Si entiendo Cypress correctamente, no debería tener que hacer nada más y se asegurará de que la página esté cargada antes de ejecutar cualquier otra cosa. Sin embargo, esto no parece funcionar porque la página está cargada, pero SystemJS todavía está cargando los módulos.

¿Cómo puedo hacer que Cypress espere a que se carguen todos los módulos de SystemJS antes de ejecutar más pruebas sin usar cy.wait(5000)?

EDITAR

Gracias a Dwelle, esta es la solución que me funciona. Envuelvo el System.import inicial en una promesa que se resuelve una vez que se ha iniciado la aplicación AngularJS.

window.APP_READY = new Promise(function(resolve, reject) {
    System.import('app').then(function(app) {
        angular.element(document).ready(function() {
            angular.bootstrap(document, ['app']);
            resolve();
        });
    });
});

Y luego en la prueba

cy.visit('http://mywebsite.com').its('APP_READY');
4
Timothy Ruhle 15 nov. 2017 a las 08:24

2 respuestas

La mejor respuesta

No estoy familiarizado con SystemJS o su aplicación, pero si asumimos que está haciendo un trabajo asincrónico en la carga, puede configurar alguna propiedad global que indique si la aplicación está lista o no.

// your main.js
let _appReadyResolver;
window.APP_READY = new Promise( resolve => _appReadyResolver = resolve );

// do some async setup
setTimeout(() => {

    _appReadyResolver();
});

Luego, en tus pruebas:

cy.visit("/")
    // by default will wait 4sec for APP_READY prop to exist on
    //  window object (unfortunately I don't know how to increase timeouts
    //  of `cy.its` command)
    // After that, it will wait indefinitely for your promise to resolve
    .its("APP_READY")

Dicho esto, si no está realizando ninguna configuración asíncrona en su aplicación, pero el main.js simplemente se está cargando de forma asincrónica y puede tardar más de 4 segundos, entonces haría esto:

// index.js
<script>
  SystemJS.import('/js/main.js');
  window.APP_READY = new Promise( resolve => {
    let interval = setInterval(() => {
        if ( window.MAIN_READY ) {
            resolve();
            clearTimeout(interval);
        };
  }, 100 );
</script>

// main.js
window.MAIN_READY = true;

Querrá quitar la lógica APP_READY de la compilación de producción.

4
dwelle 16 nov. 2017 a las 08:44

En teoría, también puedes resolver esto de una manera puramente Cypress.

Si su página realiza alguna solicitud que indique que su aplicación está lista, puede hacer que Cypress espere a que se complete antes de continuar. Puede encontrar esto más limpio que la solución APP_READY. Sin embargo, es solo una opinión, ya que este enfoque fallará si no hay solicitudes en las que pueda confiar para indicar que su aplicación está lista.

cy.server();
cy.route('**/api/getData').as('getData');
cy.visit('/home');
cy.wait('@getData');

Mejores prácticas de Cypress: Espera innecesaria.

Documentos de Cypress en espera Alias.

0
Rui Marques 8 oct. 2018 a las 12:12