4

I have scratching my heads around this problem for two days. I have a test where I need to check if a spinner is not visible to the user. This is the first test of a series of tests, and until the spinner is not visible, the page elements are not displayed to the user.

I have been trying to implement a wait in order to wait for the element to be invisible , but my tests seem to fail and the tests exit with a success code, however I can still see the spinner being available on the page.

I have even tried the dirty browser.sleep() method, but my tests doesn't even wait for the sleep duration that I have given.

I have this given block of HTML

<div class ="loadingContent">
<div class="always-loader">...</div>
<div class ="first-time-loader">
    <div>
    <div class ="text> Preparing the App just for you</div>
    <img src ="images/d92f6c4a.horizontal_loader.gif">
    </div>
</div>

My test checks that img is not present in the DOM or is not displayed. I have a function that waits for this purpose

Try 1

  public waitForSpinnerDisappear(){
  browser.sleep(100000);
    let EC = protractor.ExpectedConditions; 
    const condition = until.elementIsNotVisible($('[src="images/d92f6c4a.horizontal_loader.gif"]'));
    return browser.wait(condition,500000);

 }

Try2

  let EC = protractor.ExpectedConditions;

browser.wait(EC.invisibilityOf($('[src="images/d92f6c4a.horizontal_loader.gif"]')),500000);

Try3

public waitForSpinnerDisappear(){
browser.wait(function(){
  return $('[src="images/d92f6c4a.horizontal_loader.gif"]').isDisplayed()
  .then(function(result){
    return !result;
  });
  },500000);

 }

All these conditions doesn't wait for the spinner to disappear from the page and my tests exit with a success code

  1 scenario (1 passed)
  2 steps (2 passed)
  0m00.005s


[12:04:20] I/launcher - 0 instance(s) of WebDriver still running
[12:04:20] I/launcher - chrome #01 passed
Done in 19.54s.

I can't provide the URL for the application since it's an internal application but I can give the gist for the code in case it's needed. My question here is what do I need to do more in order for the web page to load for the spinner to be loaded.

I have gone through the following SO post's for reference but the solutions given here doesn't work

Edit : After some more debugging, I believe that this is something related to Cucumber. I had the same code without Cucumber and my tests wait for the loader to disappear.

Can someone point me in the direction where the issue might be ?

  • That d92f6c4a part in the selector looks auto-generated to me - are you sure [src="images/d92f6c4a.horizontal_loader.gif"] matches the spinner element during your test run? What if you change the locator to .first-time-loader img[src*=loader]? Thanks. – alecxe Oct 16 '17 at 12:37
  • Well thed92f6c4a part is not auto-generated. I used the locator as mentioned but it didn't work out. – demouser123 Oct 16 '17 at 12:54
  • Does the spinner remain in the DOM after it becomes invisible? One problem I have run into with waiting for an element to not exist is that sometimes the check occurs before it is initially loaded in the DOM in the first place. In those scenarios, when I know the element should appear at least for an instant, I will first wait for the element to exist then wait for it to not exist. Of course this tidbit isn't helpful if the problem is indeed caused by Cucumber. – VanderLinden Oct 16 '17 at 16:49
  • @VanderLinden the spinner doesn't remain in the DOM post becoming invisible. Although I have got a working solution, I highly doubt that is is brittle and prone to failure. Please see the answer. – demouser123 Oct 17 '17 at 4:51
  • @demouser123 Yes It is ajax/jquery loader. It appears only in specific conditions. Now identify the conditions like 1. Scroll Down 2. Click on some element 3. Hover on some element etc. Then first perform that event and try to fetch loader. Now for the stopping it. See this stackoverflow.com/questions/30895515/… – Sagar007 Oct 23 '17 at 9:16
4

After a long hard fought battle, I was able to overcome this using opposite of what K-8 had suggested.

Instead of checking if an element is visible on the viewport, I checked the negative of that, which is if element is not visible on the viewport.

So, I did this

public waitForSpinnerDisappear(){    
let EC = protractor.ExpectedConditions;
browser.wait(EC.not(EC.visibilityOf($(element_locator))));
}

In my tests, I am using async/await so, I paired my test in a Step Def like this

   Given(/^User waits for some time for spinner to disappear$/, async ()=>{

   await pageobject.waitForSpinnerDisappear();
 });

It's worth noting that I was able to overcome this using visibilityOf which is defined by Protractor API as

An expectation for checking that an element is present on the DOM of a page and visible. Visibility means that the element is not only displayed but also has a height and width that is greater than 0. This is the opposite of 'invisibilityOf'.

However, if I use invisibilityOf (as in Try 2), the test fails.

I would welcome suggestions as to how I can improve this even further.

0

Use ExpectedConditions.stalenessOf ?

Which is better suited in this scenario as you need to wait until a certain element is no longer attached to the DOM.

ProtractorExpectedConditions

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.