How I can check whether a page is loaded completely or not in web driver?

前端 未结 9 1814
走了就别回头了
走了就别回头了 2020-12-01 01:33

I am writing some Java Webdriver code to automate my application. How can I correctly check whether the page has been loaded or not? The application has some Ajax calls, too

相关标签:
9条回答
  • 2020-12-01 02:21

    Below is some code from my BasePageObject class for waits:

    public void waitForPageLoadAndTitleContains(int timeout, String pageTitle) {
        WebDriverWait wait = new WebDriverWait(driver, timeout, 1000);
        wait.until(ExpectedConditions.titleContains(pageTitle));
    }
    
    public void waitForElementPresence(By locator, int seconds) {
        WebDriverWait wait = new WebDriverWait(driver, seconds);
        wait.until(ExpectedConditions.presenceOfElementLocated(locator));
    }
    
    public void jsWaitForPageToLoad(int timeOutInSeconds) {
        JavascriptExecutor js = (JavascriptExecutor) driver;
        String jsCommand = "return document.readyState";
    
        // Validate readyState before doing any waits
        if (js.executeScript(jsCommand).toString().equals("complete")) {
            return;
        }
    
        for (int i = 0; i < timeOutInSeconds; i++) {
            TimeManager.waitInSeconds(3);
            if (js.executeScript(jsCommand).toString().equals("complete")) {
                break;
            }
        }
    }
    
       /**
         * Looks for a visible OR invisible element via the provided locator for up
         * to maxWaitTime. Returns as soon as the element is found.
         *
         * @param byLocator
         * @param maxWaitTime - In seconds
         * @return
         *
         */
        public WebElement findElementThatIsPresent(final By byLocator, int maxWaitTime) {
            if (driver == null) {
                nullDriverNullPointerExeption();
            }
            FluentWait<WebDriver> wait = new FluentWait<>(driver).withTimeout(maxWaitTime, java.util.concurrent.TimeUnit.SECONDS)
                    .pollingEvery(200, java.util.concurrent.TimeUnit.MILLISECONDS);
    
            try {
                return wait.until((WebDriver webDriver) -> {
                    List<WebElement> elems = driver.findElements(byLocator);
                    if (elems.size() > 0) {
                        return elems.get(0);
                    } else {
                        return null;
                    }
                });
            } catch (Exception e) {
                return null;
            }
        }
    

    Supporting methods:

         /**
         * Gets locator.
         *
         * @param fieldName
         * @return
         */
        public By getBy(String fieldName) {
            try {
                return new Annotations(this.getClass().getDeclaredField(fieldName)).buildBy();
            } catch (NoSuchFieldException e) {
                return null;
            }
        }
    
    0 讨论(0)
  • 2020-12-01 02:22

    Here is how I would fix it, using a code snippet to give you a basic idea:

    public class IFrame1 extends LoadableComponent<IFrame1> {
    
        private RemoteWebDriver driver;
    
        @FindBy(id = "iFrame1TextFieldTestInputControlID" ) public WebElement iFrame1TextFieldInput;
        @FindBy(id = "iFrame1TextFieldTestProcessButtonID" ) public WebElement copyButton;
    
        public IFrame1( RemoteWebDriver drv ) {
            super();
            this.driver = drv;
            this.driver.switchTo().defaultContent();
            waitTimer(1, 1000);
            this.driver.switchTo().frame("BodyFrame1");
            LOGGER.info("IFrame1 constructor...");
        }
    
        @Override
        protected void isLoaded() throws Error {        
            LOGGER.info("IFrame1.isLoaded()...");
            PageFactory.initElements( driver, this );
            try {
                assertTrue( "Page visible title is not yet available.", 
                        driver.findElementByCssSelector("body form#webDriverUnitiFrame1TestFormID h1")
                        .getText().equals("iFrame1 Test") );
            } catch ( NoSuchElementException e) {
                LOGGER.info("No such element." );
                assertTrue("No such element.", false);
            }
        }
    
        /**
         * Method: load
         * Overidden method from the LoadableComponent class.
         * @return  void
         * @throws  null
         */
        @Override
        protected void load() {
            LOGGER.info("IFrame1.load()...");
            Wait<WebDriver> wait = new FluentWait<WebDriver>( driver )
                    .withTimeout(30, TimeUnit.SECONDS)
                    .pollingEvery(5, TimeUnit.SECONDS)
                    .ignoring( NoSuchElementException.class ) 
                    .ignoring( StaleElementReferenceException.class ) ;
            wait.until( ExpectedConditions.presenceOfElementLocated( 
                    By.cssSelector("body form#webDriverUnitiFrame1TestFormID h1") ) );
        }
    ....
    
    0 讨论(0)
  • 2020-12-01 02:22

    You can get the HTML of the website with driver.getPageSource(). If the html does not change in a given interval of time this means that the page is done loading. One or two seconds should be enough. If you want to speed things up you can just compare the lenght of the two htmls. If their lenght is equal the htmls should be equal and that means the page is fully loaded. The JavaScript solution did not work for me.

    0 讨论(0)
提交回复
热议问题