简体   繁体   中英

angular.js e2e test and $timeout issue

I have a simple service for displaying flash messages https://github.com/lucassus/mongo_browser/blob/master/app/assets/javascripts/app/services.js.coffee#L31 and I'm trying to test it in e2e specs https://github.com/lucassus/mongo_browser/blob/master/spec/javascripts/e2e/databases_scenario.js.coffee#L66 I use $timeout service to hide a flash message after 3 seconds.

I noticed that e2e scenario runner blocks until the timeout flushes and I'm not able to check whether the flash message has been shown.

How to test features with $timeout in e2e specs? Is it possible to test this kind of behavior without injecting mock services into the real application?

I don't see a way to call inject() in the end-to-end tests, as described by @christian-smith; this method is for the standard Jasmine tests, not the e2e test runner.

I've created a Plunker to demonstrate.

In the example, the call to $timeout(halfHourAction, 30*1000, false); in app.js means the tests don't start running for 30 seconds.

In my Real World® example, I'm actually polling something every 30minutes, so the app never starts running at all. Even being able to flush the $browser s queue would only add another method to it.

You can use sleep(seconds) to make the test wait until your $timeout code has finished. See the API section on this page in the documentation: http://docs.angularjs.org/guide/dev_guide.e2e-testing

Also, $timeout has a flush() method you might find helpful. Just inject $timeout into your test and call flush before any assertions.

We had similar problem with $timeout - our app had to do an XHR every 5 mins - so we had a function that set a re-occurring $timeout every 5mins. This broke our e2e tests, as they were waiting for angular to finish its work before continuing, which never happened.

Heres my workaround to this problem:

  • The timeout value was moved as a configuration, which was then mocked - in the real version of our app, the value comes from the backend, in the test-version of our app, we used ngMockE2E to mock the timeout value.

  • In the test mock, the interval for the timeout was set to 0ms.

  • In the function that sets the $timeout, we have added a normal javascript setTimeout(..., 1000) which wait for 1s before setting a new $timeout.

This way, there is 1s interval between calling $timeout. When e2e tests are run, every 1s a new $timeout (0ms) is added which executes immediately and the tests continue. This has ~ 0 impact to the performance of our e2e tests and is working pretty good for now.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM