Denis Koreyba
Denis Koreyba

Reputation: 3718

Wait for page loading using PageFactory C#

I'm using PageFactory in my selenium tests. And I've faced a problem in waiting for loading page. I'm not talking about an element on a page I'm talking about timeout of page loading. So, I have a method like the following:

 public MyProjectsPage ClickSaveAndCloseButton()
        {
            //Do something and click a button
            SaveAndCloseButton.Click();

            return new MyProjectsPage(Driver); //return new page
        }

And when I'm waiting for returning new PageObject (in my case it is "MyProjectsPage") I got a timeout exception. So, where can I set a page loading timeout?

Actual mistake looks like this:

AutomatedTests.FrontEnd.SouvenirProduct.SouvenirTestExecution.OrderSouvenirWithAuthorization(ByCash,Pickup,True,Cup):
OpenQA.Selenium.WebDriverException : The HTTP request to the remote WebDriver server for URL http://localhost:7585/session/b68c04d1ead1fc78fe083e06cbece38f/element/0.46564483968541026-14/click timed out after 60 seconds.
  ----> System.Net.WebException : The operation has timed out

I have: The latest version of WebDriver And the latest version of ChromeDriver and the latest version of Chrome Browser The mistake that is above apears int the next line:

return new MyProjectsPage(Driver); //return new page

I create my ChromeDriver the next way:

 public DriverCover(IWebDriver driver)
        {
            _driver = driver;
            _driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
        }

        private readonly IWebDriver _driver;

Upvotes: 0

Views: 2124

Answers (3)

LoflinA
LoflinA

Reputation: 350

// Wait Until Object is Clickable
    public static void WaitUntilClickable(IWebElement elementLocator, int timeout)
    {
        try
        {
            WebDriverWait waitForElement = new WebDriverWait(DriverUtil.driver, TimeSpan.FromSeconds(10));
            waitForElement.Until(ExpectedConditions.ElementToBeClickable(elementLocator));
        }
        catch (NoSuchElementException)
        {
            Console.WriteLine("Element with locator: '" + elementLocator + "' was not found in current context page.");
            throw;
        }
    }

    // Wait For Page To Load
    public static void WaitForPage()
    {
        new WebDriverWait(DriverUtil.driver, MyDefaultTimeout).Until(
            d => ((IJavaScriptExecutor)d).ExecuteScript("return document.readyState").Equals("complete"));
    }

Upvotes: 0

Jamie Rees
Jamie Rees

Reputation: 8183

What you should really be doing when using the PageFactory pattern is when initialising your Page you should be using a constructor to initialise the elements.

public MyProjectsPage ClickSaveAndCloseButton()
{
        //Do something and click a button
        //I am guessing this is taking you to the MyProjectsPage
        SaveAndCloseButton.Click();

        return new MyProjectsPage(Driver); //return new page
}


public class MyProjectsPage
{

    [FindsBy(How = How.Id, Using = "yourId")]
    public IWebElement AWebElement { get; set; }

    private IWebDriver WebDriver;

    public MyProjectsPage (IWebDriver webDriver)
    {
        WebDriver = webDriver;
        PageFactory.InitElements(WebDriver, this);
    }   

}

When you return the page, all elements using the FindsBy attribute will be initialised.

Update:

set this property on the driver when you initialise it:

WebDriver.Manage().Timeouts().SetPageLoadTimeout(timespan)

Upvotes: 1

eugene.polschikov
eugene.polschikov

Reputation: 7339

1 note considering wait mechanisms on the page: Take a couple of webElements and apply for them fluentWait() . That'll be explicit wait webdriver approach.

Another approach is to try out implicit wait like:

int timeToWait=10;
driver.manage().timeouts().implicitlyWait(timeToWait, TimeUnit.SECONDS);

Considering you pageObject code: I would recommed you the following:

MyPage myPageInstance= PageFactory.initElements(driver, MyPage.class);

then you write the following method :

public MyPage clickSaveAndOtherActions(MyPage testPageToClick)
        {
            testPageToClick.clickFirstButton();
            testPageToClick.clickSecondButton();
            testPageToClick.closePoPup();


            return testPageToClick; //return page in a new state
    }

and if you wanna continue working (I mean update your page state) you do the following:

  myPageInstance = clickSaveAndOtherActions(myPageInstance ); 

Hope this helps you. Thanks.

UPD : as I see from the log something looks wrong with remoteWebdriver server:

OpenQA.Selenium.WebDriverException : The HTTP request to the remote WebDriver server for URL http://localhost:7585/session/b68c04d1ead1fc78fe083e06cbece38f/element/0.46564483968541026-14/click timed out after 60 seconds. ----> System.Net.WebException : The operation has timed out

Also, I'd recommend you to double check you driver method init. I'm using the following piece of java code for driver init (UI , chrome instance, selenium grid+ hub nodes test architecture):

public static WebDriver driverSetUp(WebDriver driver) throws MalformedURLException {
        DesiredCapabilities capability = DesiredCapabilities.chrome();
        log.info("Google chrome is selected");
        //System.setProperty("webdriver.chrome.driver", System.getProperty("user.home")+"/Documents/Tanjarine/chromedriver");
        System.setProperty("webdriver.chrome.driver", "chromedriver.exe");
        capability.setBrowserName("chrome");
        capability.setPlatform(org.openqa.selenium.Platform.WINDOWS);


        String webDriverURL = "http://" + environmentData.getHubIP() + ":" + environmentData.getHubPort() + "/wd/hub";
        driver = new RemoteWebDriver(new URL(webDriverURL), capability);
        driver.manage().timeouts().implicitlyWait(20, TimeUnit.SECONDS);
        driver.manage().timeouts().pageLoadTimeout(30, TimeUnit.SECONDS);
        driver.manage().window().setSize(new Dimension(1920, 1080));

        return driver;

    }

Upvotes: 1

Related Questions