赛普拉斯与SystemJS

时间:2017-11-15 05:24:27

标签: javascript testing systemjs es6-modules cypress

我正在尝试创建一些基本测试来试用新的Cypress库。在我的测试中,我有cy.visit('http://mywebsite.com');正在加载使用SystemJS的AngularJS应用程序。

如果我正确理解赛普拉斯,我不应该做任何其他事情,它会确保在运行其他任何内容之前加载页面。但是,由于页面已加载,但似乎无法正常工作,但SystemJS仍在加载模块。

如何在不使用cy.wait(5000)的情况下运行任何更多测试之前让赛普拉斯等待所有SystemJS模块加载?

修改

感谢Dwelle,这是适合我的解决方案。我将初始System.import包装在一个AngularJS应用程序被引导后解析的promise中。

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

然后在测试中

cy.visit('http://mywebsite.com').its('APP_READY');

2 个答案:

答案 0 :(得分:3)

不熟悉SystemJS或您的应用程序,但如果我们假设您在加载时进行了一些异步工作,则可以设置一些全局属性来指示应用程序是否已准备就绪。

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

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

    _appReadyResolver();
});

然后,在你的测试中:

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")

话虽如此 - 如果你没有在你的应用程序中进行任何异步设置,但是main.js只是异步加载而且可能需要超过4秒,那么我就是这样做:

// 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;

您希望从生产版本中删除APP_READY逻辑。

答案 1 :(得分:0)

从理论上讲,您也可以采用纯赛普拉斯的方式解决此问题。

如果您的页面提出了任何指示您的应用已准备就绪的请求,则可以让Cypress等待其完成,然后再继续进行。您可能会发现此清洁器比APP_READY解决方案更清洁。不过,这只是一个意见,因为如果没有您可以信任的信号来表明您的应用已准备就绪,这种方法将失败。

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

Cypress best practices: Unnecessary-Waiting.

Cypress docs on wait Alias.