0

In some of my projects to correctly save forms user needs to perform click on "Save" or "Save changes" button. That click cause whole page to reload (changes done will be visible on page after that reload), but if something is wrong validation will stops page from reloading. I want to create a simple assertion to check if that page was reloaded, if not my test will fail. I tried to use this code:

public bool WasPageRefreshed(float seconds)
{
    DriverLocal.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.MinValue);
    string getReadyState = "return document.readyState;";

    for (int i = 0; i < 10; i++)
    {
        string readyState = GetJsExecutor().ExecuteScript(getReadyState) as string;
        if (readyState != "complete")
            return true;
        Thread.Sleep(TimeSpan.FromMilliseconds(seconds / 10));
    }

    DriverLocal.Manage().Timeouts().SetPageLoadTimeout(TimeSpan.FromSeconds(60));
    return false;
}

I use it in Assert.True() to check if page was reloaded but it doesn't work always (I can use it 5 times on same form - 3 times its ok, 2 times test will fail). Is there a way to upgrade it to work correctly in 100% of usage? Or maybe there is another way to check if page was reloaded?

Kurt Van den Branden
  • 11,995
  • 10
  • 76
  • 85

3 Answers3

1

For Webpage load, there is unfortunately no one size fits all solution. Every situation varies. How you wait in your automation suite is very critical. Explicit waits are recommended way of waiting, instead of using Javascript options, you can just wait for a new element after the page load or wait for invisibility of certain element that tells you that the page is loaded

 new WebDriverWait(driver, TimeSpan.FromSeconds(timeOut))
.Until(ExpectedConditions
.ElementExists((By.Id("new Element Id"))));

or

 new WebDriverWait(driver, TimeSpan.FromSeconds(timeOut))
.Until(ExpectedConditions
.InvisibilityOfElementLocated((By.Id("old Element Id"))));

You can check ExpectedElements docs here

nilesh
  • 14,131
  • 7
  • 65
  • 79
  • [C# ExpectedConditions is marked obsolete](https://stackoverflow.com/questions/49866334) and has been moved to [DotNetSeleniumExtras](https://github.com/DotNetSeleniumTools/DotNetSeleniumExtras), see [Deprecating Parts of Selenium's .NET Bindings](http://jimevansmusic.blogspot.com/2018/03/deprecating-parts-of-seleniums-net.html) for the rationale. – Dave Anderson Sep 23 '19 at 23:34
0

There may be some Ajax call works asynchronously. You can wait until ajax call finished, then do your case, see this:

public void WaitForAjax()
{
    while (true) // break if ajax return false
    {
        var ajaxIsComplete = (bool)(driver as IJavaScriptExecutor).ExecuteScript("return jQuery.active == 0");
        if (ajaxIsComplete)
            break;
        Thread.Sleep(100);
    }
}
Mesut GUNES
  • 7,089
  • 2
  • 32
  • 49
  • That wont help, if I will wait for all Ajax to complete then page will be loaded and ready to use. I need to check if page is reloading while its reloading. – Filip Lipiński Aug 10 '16 at 09:39
  • Your case different than checking loading. Why don't you find an object that should be present after "save" button and checking it for assertion? – Mesut GUNES Aug 10 '16 at 10:08
  • @MesutGüneş Problem is that after "save" page looks exactly the same like before saving. So checking if that page element is present will won't give me nothing (assertion on this element will always find it ). – Filip Lipiński Aug 11 '16 at 07:11
  • you said "That click cause whole page to reload (changes done will be visible on page after that reload)" you can check this changes. Or check what should happen in database – Mesut GUNES Aug 11 '16 at 07:16
  • It seems that this is only solution for me. Database check seems to be only solution for this case. – Filip Lipiński Aug 11 '16 at 07:20
0

As my opinion, you better use SeleniumWait instead of Sleep. Try this

        public bool WasPageRefreshed(double seconds)
    {
        WebDriverWait wait = new WebDriverWait(DriverLocal, TimeSpan.FromSeconds(seconds));
        wait.PollingInterval = TimeSpan.FromSeconds(1);
        string getReadyState = "return document.readyState;";
        try
        {
            wait.Until(d =>
            {
                string readyState = GetJsExecutor().ExecuteScript(getReadyState) as string;
                if (readyState == "complete")
                    return true;
            });
        }
        catch (Exception)
        {
        }
        return false;
    }

I suggest you Wait for a specific element that marked the status of a refreshed page.

Viet Pham
  • 214
  • 2
  • 5