Waiting for Ionic Loading dialogs with Protractor
Asked Answered
M

1

10

There are similar questions (linked below) but none solves this problem. I'm writing Protractor tests for an Ionic Project. I need to execute tests at times when an Ionic Loading dialog appears and disappears.

I've created a repo with the bare bones of the app and the tests that need to be made. Solve this and you solve the problem (I describe the problem below): https://github.com/TmanTman/StackoverflowQ. Just adapt the path to your Chrome for your system in conf.js.

To simulate an asynchronous Ionic Loading dialog I just add this to the controller in a blank Ionic project:

$interval( function() {
        $ionicLoading.show({
            template: 'Async ionicLoading',
            duration: 5000
        });
      }, 5000 , 1);
    })

I need to get protractor to wait for the dialog to appear, do some tests, wait for the dialog to disappear, and then do some more tests. My latest attempt in my test file is:

it('should only test when ionicLoading appears', function() {
  browser.wait(function(){
    return element(by.css('.loading-container.visible.active')).isPresent();
  }, 10000);
  var ionicLoadingText = element(by.css('.loading-container.visible.active')).getText();
  expect(ionicLoadingText).toEqual('Async IonicLoading');
})



it('should only test once ionicLoading disappears', function() {
  browser.wait(function() {
    var deferred = protractor.promise.defer();
    var q = element(by.css('.loading-container.visible.active')).isPresent()
      q.then( function (isPresent) {
        deferred.fulfill(!isPresent);
      });
      return deferred.promise;
    });
  expect(1).toEqual(1);
})

I'm trying to avoid using synchronous sleep function, as my code is highly asynchronous. I've tried countless variations but I can't get it to work. Links I've used for info includes:

Merimerida answered 13/6, 2015 at 10:9 Comment(2)
What errors do you have? Does the expectation in first block execute before the dialog appears or is there a timeout error?Acquaintance
Timeout error on the first block: "Failed: Wait timed out after 10472ms".Merimerida
M
7

The problem is two-fold:

1) From what I can deduce, the duration property of the $ionicLoading method is implemented with a timeout function. Protractor does not work well with $timeout. So instead of using the duration property, the $ionicLoading dialog can be hidden with a $interval call (adapting the code from the question):

$interval( function() {
      $ionicLoading.show({
          template: 'Async IonicLoading'
      });
      $interval( function() {
        $ionicLoading.hide();
      }, 5000, 1)
  }, 5000 , 1);

2) The code to detect the asynchronous change is the following:

it('should only test when ionicLoading appears', function() {
    browser.wait(function() {
      var deferred = protractor.promise.defer();
      var q = element(by.css('.loading-container.visible.active')).isPresent()
      q.then( function (isPresent) {
          deferred.fulfill(isPresent);
      });
      return deferred.promise;
    }, 10000);
      var ionicLoadingText = element(by.css('.loading-container.visible.active')).getText();
      expect(ionicLoadingText).toEqual('Async IonicLoading');
    })

    it('should only test once ionicLoading disappears', function() {
      browser.wait(function() {
        var deferred = protractor.promise.defer();
        var q = element(by.css('.loading-container.visible.active')).isPresent()
          q.then( function (isPresent) {
            deferred.fulfill(!isPresent);
          });
          return deferred.promise;
        }, 10000);
      expect(1).toEqual(1);
    })

Then both tests pass.

Merimerida answered 20/6, 2015 at 9:55 Comment(3)
Nice catch! ionicLoading.duration uses $timeout indeed. Excellent example of a leaky abstraction when used with Protractor.Obtrude
I've asked on the Ionic forum whether I should try and implement the ionicLoading.duration property with a $interval rather than $timeout forum.ionicframework.com/t/…Merimerida
You should :-) Go for it!Obtrude

© 2022 - 2024 — McMap. All rights reserved.