Selenium đợi cho đến khi tài liệu đã sẵn sàng


133

Bất cứ ai có thể cho tôi làm thế nào tôi có thể làm cho selen chờ cho đến khi trang tải hoàn toàn? Tôi muốn một cái gì đó chung chung, tôi biết tôi có thể định cấu hình WebDriverWait và gọi một cái gì đó như 'tìm' để làm cho nó chờ nhưng tôi không đi xa đến thế. Tôi chỉ cần kiểm tra rằng trang tải thành công và chuyển sang trang tiếp theo để kiểm tra.

Tôi đã tìm thấy một cái gì đó trong .net nhưng không thể làm cho nó hoạt động trong java ...

IWait<IWebDriver> wait = new OpenQA.Selenium.Support.UI.WebDriverWait(driver, TimeSpan.FromSeconds(30.00));
wait.Until(driver1 => ((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete"));

Có ai nghĩ gì không?


Tại sao bạn không muốn sử dụng chờ đợi?
Amey

7
Bạn có nghĩa là chờ đợi rõ ràng? Nó tốn thời gian, tôi đang thử nghiệm một số trang 10k.
Girish

2
Ý tôi là, thêm một chờ đợi sửa chữa có thể không phải là một ý tưởng tốt nếu tôi đang thử nghiệm một số lượng lớn các liên kết, phải không?
Girish

10
Chờ đợi một số giây cố định là không sử dụng. Đó là đoán.
Anders Lindén

Cho rằng javascript của một trang có thể chạy bất kỳ mã chung nào, việc viết chương trình để chờ hoàn thành là không thể. Đây là một dạng của vấn đề dừng ( en.wikipedia.org/wiki/Halting_pro Hiệu ). Bất kỳ giải pháp nào ở đây sẽ cần phải thỏa hiệp hoặc dựa trên các giả định của trang web cơ bản.
siêu tốc độ

Câu trả lời:


83

Hãy thử mã này:

  driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);

Đoạn mã trên sẽ đợi tối đa 10 giây để tải trang. Nếu tải trang vượt quá thời gian nó sẽ ném TimeoutException. Bạn bắt ngoại lệ và làm nhu cầu của bạn. Tôi không chắc liệu nó có thoát khỏi trang tải sau khi ném ngoại lệ hay không. tôi chưa thử mã này. Muốn thử nó.

Đây là một chờ đợi ngầm. Nếu bạn thiết lập điều này một lần, nó sẽ có phạm vi cho đến khi cá thể Trình điều khiển web hủy.

Xem tài liệuWebDriver.Timeouts để biết thêm.


3
Cảm ơn, vậy điều gì xảy ra ở đây nếu trang được tải trước 10 giây, liệu nó có còn đợi 10 giây để thực hiện dòng tiếp theo sau khi tải không?
Girish

Không, nếu trang của bạn tải trước 10 giây có nghĩa là nó sẽ chấm dứt điều kiện chờ và thực thi dòng trước.
Manigandan

3
Điều này được sử dụng khi bạn mong đợi tải trang mất quá nhiều thời gian để hết thời gian chờ và ném ngoại lệ, nó không phải là chờ đợi để tải trang hoặc đặt chính sách tải tốt hơn. Nó mặc định theo thời gian vô hạn, vì vậy tải trang của bạn không bao giờ ném ngoại lệ và Selenium luôn cố gắng chờ chúng tải hoàn toàn.
Petr Janeček

19
Vấn đề với phương pháp này là có thể DOM không hoàn toàn có thể truy cập được mặc dù chờ đợi ngầm đã trả về thành công một đối tượng WebEuity. Sau đó, nếu bạn cố gắng nhấp vào phần tử, bạn sẽ nhận được một ngoại lệ phần tử cũ. Vì vậy, câu trả lời này không hoàn toàn an toàn.
djangofan

3
Làm thế nào là thời gian chờ này liên quan đến việc chờ đợi một tài liệu được tải?
Anders Lindén

90

Giải pháp đề xuất của bạn chỉ chờ DOMreadyState báo hiệu complete. Nhưng Selenium theo mặc định cố gắng chờ đợi những thứ đó (và một chút nữa) khi tải trang thông qua các phương thức driver.get()element.click(). Họ đã chặn, họ chờ trang tải đầy đủ và những trang đó sẽ hoạt động tốt.

Vấn đề, rõ ràng, là các chuyển hướng thông qua các yêu cầu AJAX và các tập lệnh đang chạy - chúng không thể bị bắt bởi Selenium, nó không chờ chúng kết thúc. Ngoài ra, bạn không thể bắt chúng một cách đáng tin cậy readyState- nó chờ một chút, điều này có thể hữu ích, nhưng nó sẽ báo hiệu completerất lâu trước khi tất cả nội dung AJAX được tải xuống.

Không có giải pháp chung nào có thể hoạt động ở mọi nơi và cho mọi người, đó là lý do tại sao nó khó và mọi người sử dụng một chút gì đó khác biệt.

Nguyên tắc chung là dựa vào WebDriver để thực hiện phần của mình, sau đó sử dụng chờ đợi ngầm, sau đó sử dụng chờ đợi rõ ràng cho các yếu tố bạn muốn xác nhận trên trang, nhưng có rất nhiều kỹ thuật có thể được thực hiện. Bạn nên chọn một (hoặc một sự kết hợp của một vài trong số chúng) hoạt động tốt nhất trong trường hợp của bạn, trên trang thử nghiệm của bạn.

Xem hai câu trả lời của tôi về điều này để biết thêm thông tin:


20
Điều đó không chính xác, Selenium không chờ đợi hoặc chặn element.click()cuộc gọi.
hwjp

3
@hwjp Quan tâm đến công phu hơn? JavaDocs nói khác : "Nếu điều này khiến một trang mới tải, phương thức này sẽ cố gắng chặn cho đến khi trang được tải."
Petr Janeček

5
cf một số cuộc hội thoại tôi đã có trong danh sách gửi thư có vẻ như không chính xác. selenium có thể chặn các cuộc gọi .get trong đó bạn yêu cầu URL rõ ràng, nhưng nó không có gì đặc biệt đối với các cuộc gọi nhấp chuột, bởi vì nó không thể cho biết bạn đã nhấp vào một siêu liên kết "thực" hay trên một liên kết sẽ bị chặn bởi javascript. ..
hwjp

4
Tôi liên kết đến một lỗi khi bắt đầu cuộc thảo luận danh sách gửi thư. Ngay cả các tài liệu tương đương: "Nếu nhấp () [...] được thực hiện bằng cách gửi một sự kiện riêng thì phương thức sẽ * không * chờ"
hwjp

4
Vì vậy, tất cả bật lên cho dù trình duyệt đang sử dụng "sự kiện gốc". Và có vẻ như hầu hết trong số họ sẽ, theo mặc định: code.google.com/p/selenium/wiki/ Khăn (vì vậy tôi muốn nói rằng những tài liệu đó là sai lệch nhất. Sẽ ping danh sách gửi thư).
hwjp

61

Đây là phiên bản Java hoạt động của ví dụ bạn đã đưa ra:

void waitForLoad(WebDriver driver) {
    new WebDriverWait(driver, 30).until((ExpectedCondition<Boolean>) wd ->
            ((JavascriptExecutor) wd).executeScript("return document.readyState").equals("complete"));
}

Ví dụ cho c #:

public static void WaitForLoad(IWebDriver driver, int timeoutSec = 15)
{
  IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
  WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 0, timeoutSec));
  wait.Until(wd => js.ExecuteScript("return document.readyState").ToString() == "complete");
}

1
Anh bạn, tôi đang sao chép / dán cái này. Đoạn trích này chỉ là tuyệt vời. Tại sao tôi không nghĩ về điều này? Sự thật là nhiều hơn một cặp nhãn cầu luôn dẫn đến một giải pháp tốt. Cảm ơn.
luis.espinal

2
Bạn có thể đặt phiên bản này trong phiên bản java 1.7 tương thích vì các biểu thức lambda không hỗ trợ
vkrams

3
Phiên bản Java 1.7: Wait.until (Dự đoán mới <WebDriver> () {áp dụng boolean công khai (trình điều khiển WebDriver) {return ((JavascriptExecutor) trình điều khiển) .executeScript ("return document. YetState"). Bằng ("hoàn thành");} });
luQ

1
Nếu ai đó muốn sử dụng giải pháp của @IuQ thì, Dự đoán đã nhậpimport com.google.common.base.Predicate
Knu8

Tôi đã thử ý tưởng này trong một ứng dụng thử nghiệm VB. Hoạt động hầu hết thời gian. Đôi khi tôi gặp lỗi này: System.InvalidOperationException: Lỗi JavaScript (Un XếpJavaScriptError) tại OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError (Phản hồi lỗiResponse) Ứng dụng thử nghiệm nhấp vào liên kết trình đơn cấp 2, sau đó D, InternetExplorerDriver) .ExecuteScript ("return document. YetState") = "hoàn thành"). Tôi nghĩ rằng lỗi là do trình duyệt tải trang hiện tại và không phải là đối tượng tài liệu. Có thể đợi 1/2 giây trước khi thực hiện "return document.readystate? Ý tưởng?
CoolBreeze

12

Đây là nỗ lực của tôi tại một giải pháp hoàn toàn chung chung, trong Python:

Đầu tiên, một chức năng "chờ" chung (sử dụng WebDriverWait nếu bạn thích, tôi thấy chúng xấu xí):

def wait_for(condition_function):
    start_time = time.time()
    while time.time() < start_time + 3:
        if condition_function():
            return True
        else:
            time.sleep(0.1)
    raise Exception('Timeout waiting for {}'.format(condition_function.__name__))

Tiếp theo, giải pháp dựa trên thực tế là selen ghi lại số id (nội bộ) cho tất cả các thành phần trên một trang, bao gồm cả thành <html>phần cấp cao nhất. Khi một trang làm mới hoặc tải, nó nhận được một phần tử html mới với ID mới.

Vì vậy, giả sử bạn muốn nhấp vào một liên kết với văn bản "liên kết của tôi" chẳng hạn:

old_page = browser.find_element_by_tag_name('html')

browser.find_element_by_link_text('my link').click()

def page_has_loaded():
    new_page = browser.find_element_by_tag_name('html')
    return new_page.id != old_page.id

wait_for(page_has_loaded)

Để có thêm trình trợ giúp chung, có thể tái sử dụng, Pythonic, bạn có thể tạo trình quản lý bối cảnh:

from contextlib import contextmanager

@contextmanager
def wait_for_page_load(browser):
    old_page = browser.find_element_by_tag_name('html')

    yield

    def page_has_loaded():
        new_page = browser.find_element_by_tag_name('html')
        return new_page.id != old_page.id

    wait_for(page_has_loaded)

Và sau đó bạn có thể sử dụng nó trên hầu hết mọi tương tác selen:

with wait_for_page_load(browser):
    browser.find_element_by_link_text('my link').click()

Tôi nghĩ đó là chống đạn! Bạn nghĩ sao?

Thông tin thêm trong một bài đăng blog về nó ở đây


Cách tiếp cận rất thú vị. Một thách thức là liệu điều này có thể hoạt động khi tải trang ban đầu hay không, sau khi trình duyệt được khởi chạy lần đầu tiên. Không có gì đảm bảo rằng trạng thái ban đầu của trình duyệt có bất kỳ trang nào được tải. Ngoài ra, trong Java, tôi không thấy rằng chúng ta có một 'id' trên đối tượng - Tôi cho rằng bạn không có nghĩa là selenium chèn một thuộc tính id html. Tôi sẽ thêm nhiều hơn vào phản hồi này một khi tôi đã khám phá tùy chọn này nhiều hơn. Cảm ơn vì bài đăng!
Lukus

@hwjp Tôi sử dụng giải pháp này nhiều lần với kết quả tuyệt vời, nhưng có vẻ như nó không hoạt động trong một trường hợp. Giải thích đầy đủ về vấn đề stackoverflow.com/q/31985739/4249707
El Ruso

7

Tôi đã có một vấn đề tương tự. Tôi cần đợi cho đến khi tài liệu của tôi sẵn sàng nhưng cũng cho đến khi tất cả các cuộc gọi Ajax kết thúc. Điều kiện thứ hai tỏ ra khó phát hiện. Cuối cùng, tôi đã kiểm tra các cuộc gọi Ajax đang hoạt động và nó đã hoạt động.

Javascript:

return (document.readyState == 'complete' && jQuery.active == 0)

Phương pháp C # đầy đủ:

private void WaitUntilDocumentIsReady(TimeSpan timeout)
{
    var javaScriptExecutor = WebDriver as IJavaScriptExecutor;
    var wait = new WebDriverWait(WebDriver, timeout);            

    // Check if document is ready
    Func<IWebDriver, bool> readyCondition = webDriver => javaScriptExecutor
        .ExecuteScript("return (document.readyState == 'complete' && jQuery.active == 0)");
    wait.Until(readyCondition);
}

Có cái gì đó giống như document.readyState == 'complete' && jQuery.active == 0cho React?
Rain9333

7
WebDriverWait wait = new WebDriverWait(dr, 30);
wait.until(ExpectedConditions.jsReturnsValue("return document.readyState==\"complete\";"));

4

Đối với C # NUnit, bạn cần chuyển đổi WebDriver thành JSExecuter và sau đó thực thi tập lệnh để kiểm tra xem trạng thái document. Yet đã hoàn tất hay chưa. Kiểm tra mã dưới đây để tham khảo:

 public static void WaitForLoad(IWebDriver driver)
    {
        IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
        int timeoutSec = 15;
        WebDriverWait wait = new WebDriverWait(driver, new TimeSpan(0, 0, timeoutSec));
        wait.Until(wd => js.ExecuteScript("return document.readyState").ToString() == "complete");
    }

Điều này sẽ đợi cho đến khi điều kiện được thỏa mãn hoặc hết thời gian.


3

Đối với tải trang ban đầu, tôi nhận thấy rằng "Tối đa hóa" cửa sổ trình duyệt thực tế chờ cho đến khi hoàn thành tải trang (bao gồm cả các nguồn)

Thay thế:

AppDriver.Navigate().GoToUrl(url);

Với:

public void OpenURL(IWebDriver AppDriver, string Url)
            {
                try
                {
                    AppDriver.Navigate().GoToUrl(Url);
                    AppDriver.Manage().Window.Maximize();
                    AppDriver.SwitchTo().ActiveElement();
                }
                catch (Exception e)
                {
                    Console.WriteLine("ERR: {0}; {1}", e.TargetSite, e.Message);
                    throw;
                }
            }

hơn sử dụng:

OpenURL(myDriver, myUrl);

Điều này sẽ tải trang, chờ cho đến khi hoàn thành, tối đa hóa và tập trung vào nó. Tôi không biết tại sao nó như thế này nhưng nó hoạt động.

Nếu bạn muốn đợi tải trang sau khi nhấp vào tiếp theo hoặc bất kỳ kích hoạt điều hướng trang nào khác thì "Điều hướng ()", câu trả lời của Ben Dyer (trong chuỗi này) sẽ thực hiện công việc.


1

Có một cái nhìn vào tấm thảm web-framework. Bạn có thể tải mã nguồn ở đó.

Ý tưởng là để báo hiệu rằng trang đã sẵn sàng bởi thuộc tính html của cơ thể. Bạn có thể sử dụng ý tưởng này bỏ qua các trường hợp kiện phức tạp.

<html>
<head>
</head>
<body data-page-initialized="false">
    <p>Write you page here</p>

    <script>
    $(document).ready(function () {
        $(document.body).attr('data-page-initialized', 'true');
    });
    </script>  
</body>
</html>

Và sau đó tạo phần mở rộng của Selenium webdo (theo khung tấm thảm)

public static void WaitForPageToLoad(this IWebDriver driver, int timeout = 15000)
{
    //wait a bit for the page to start loading
    Thread.Sleep(100);

    //// In a limited number of cases, a "page" is an container error page or raw HTML content
    // that does not include the body element and data-page-initialized element. In those cases,
    // there will never be page initialization in the Tapestry sense and we return immediately.
    if (!driver.ElementIsDisplayed("/html/body[@data-page-initialized]"))
    {                
        return;
    }

    Stopwatch stopwatch = Stopwatch.StartNew();

    int sleepTime = 20;

    while(true)
    {
        if (driver.ElementIsDisplayed("/html/body[@data-page-initialized='true']"))
        {
            return;
        }

        if (stopwatch.ElapsedMilliseconds > 30000)
        {
            throw new Exception("Page did not finish initializing after 30 seconds.");
        }

        Thread.Sleep(sleepTime);
        sleepTime *= 2; // geometric row of sleep time
    }          
}

Sử dụng phần mở rộng ElementIsDisplayed được viết bởi Alister Scott .

public static bool ElementIsDisplayed(this IWebDriver driver, string xpath)
{
    try
    {
        return driver.FindElement(By.XPath(xpath)).Displayed;
    }
    catch(NoSuchElementException)
    {
        return false;
    }
}

Và cuối cùng tạo thử nghiệm:

driver.Url = this.GetAbsoluteUrl("/Account/Login");            
driver.WaitForPageToLoad();

1

Câu trả lời của Ben Dryer không được biên dịch trên máy của tôi ( "The method until(Predicate<WebDriver>) is ambiguous for the type WebDriverWait").

Phiên bản Java 8 đang hoạt động:

Predicate<WebDriver> pageLoaded = wd -> ((JavascriptExecutor) wd).executeScript(
        "return document.readyState").equals("complete");
new FluentWait<WebDriver>(driver).until(pageLoaded);

Phiên bản Java 7:

Predicate<WebDriver> pageLoaded = new Predicate<WebDriver>() {

        @Override
        public boolean apply(WebDriver input) {
            return ((JavascriptExecutor) input).executeScript("return document.readyState").equals("complete");
        }

};
new FluentWait<WebDriver>(driver).until(pageLoaded);

1

Tôi đã thử mã này và nó hoạt động cho tôi. Tôi gọi chức năng này mỗi khi tôi chuyển sang trang khác

public static void waitForPageToBeReady() 
{
    JavascriptExecutor js = (JavascriptExecutor)driver;

    //This loop will rotate for 100 times to check If page Is ready after every 1 second.
    //You can replace your if you wants to Increase or decrease wait time.
    for (int i=0; i<400; i++)
    { 
        try 
        {
            Thread.sleep(1000);
        }catch (InterruptedException e) {} 
        //To check page ready state.

        if (js.executeScript("return document.readyState").toString().equals("complete"))
        { 
            break; 
        }   
      }
 }

1

Trong Nodejs, bạn có thể nhận được thông qua lời hứa ...

Nếu bạn viết mã này, bạn có thể chắc chắn rằng trang đã được tải đầy đủ khi bạn đến ...

driver.get('www.sidanmor.com').then(()=> {
    // here the page is fully loaded!!!
    // do your stuff...
}).catch(console.log.bind(console));

Nếu bạn viết mã này, bạn sẽ điều hướng và selen sẽ đợi 3 giây ...

driver.get('www.sidanmor.com');
driver.sleep(3000);
// you can't be sure that the page is fully loaded!!!
// do your stuff... hope it will be OK...

Từ tài liệu Selenium:

this .get (url) → Có thể

Lên lịch một lệnh để điều hướng đến URL đã cho.

Trả về một lời hứa sẽ được giải quyết khi tài liệu đã tải xong .

Tài liệu Selenium (Nodejs)


1

Sự chờ đợi cho sự kiện document. Yet không phải là toàn bộ vấn đề này, bởi vì mã này vẫn còn trong tình trạng chạy đua: Đôi khi mã này được kích hoạt trước khi sự kiện nhấp được xử lý để điều này trực tiếp trở lại, vì trình duyệt đã bắt đầu đang tải trang mới.

Sau khi tìm kiếm, tôi tìm thấy một bài đăng trên Obay con dê thử nghiệm , có một giải pháp cho vấn đề này. Mã c # cho giải pháp đó là như thế này:

 IWebElement page = null;
 ...
 public void WaitForPageLoad()
 {
    if (page != null)
    {
       var waitForCurrentPageToStale = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
       waitForCurrentPageToStale.Until(ExpectedConditions.StalenessOf(page));
    }

    var waitForDocumentReady = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
    waitForDocumentReady.Until((wdriver) => (driver as IJavaScriptExecutor).ExecuteScript("return document.readyState").Equals("complete"));

    page = driver.FindElement(By.TagName("html"));

}

`Tôi kích hoạt phương thức này trực tiếp sau trình điều khiển.navigate.gotourl, để nó được tham chiếu trang càng sớm càng tốt. Hãy vui vẻ với nó!


1

Normaly khi selen mở một trang mới từ một phương thức nhấp hoặc gửi hoặc nhận, nó sẽ đợi cho đến khi trang được tải nhưng vấn đề là khi trang có lệnh gọi xhr (ajax), anh ta sẽ không bao giờ đợi xhr được tải, vì vậy tạo ra một metode mới để theo dõi một xhr và chờ đợi chúng sẽ là tốt.

public boolean waitForJSandJQueryToLoad() {
    WebDriverWait wait = new WebDriverWait(webDriver, 30);
    // wait for jQuery to load
    ExpectedCondition<Boolean> jQueryLoad = new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        try {
            Long r = (Long)((JavascriptExecutor)driver).executeScript("return $.active");
            return r == 0;
        } catch (Exception e) {
            LOG.info("no jquery present");
            return true;
        }
      }
    };

    // wait for Javascript to load
    ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
      @Override
      public Boolean apply(WebDriver driver) {
        return ((JavascriptExecutor)driver).executeScript("return document.readyState")
        .toString().equals("complete");
      }
    };

  return wait.until(jQueryLoad) && wait.until(jsLoad);
}

if $.active == 0vì vậy, không có cuộc gọi xhrs hoạt động (chỉ hoạt động với jQuery). đối với cuộc gọi ajax javascript, bạn phải tạo một biến trong dự án của bạn và mô phỏng nó.


0

Bạn có thể viết một số logic để xử lý này. Tôi đã viết một phương thức sẽ trả về WebElementvà phương thức này sẽ được gọi ba lần hoặc bạn có thể tăng thời gian và thêm kiểm tra null cho WebElementDưới đây là một ví dụ

public static void main(String[] args) {
        WebDriver driver = new FirefoxDriver();
        driver.get("https://www.crowdanalytix.com/#home");
        WebElement webElement = getWebElement(driver, "homekkkkkkkkkkkk");
        int i = 1;
        while (webElement == null && i < 4) {
            webElement = getWebElement(driver, "homessssssssssss");
            System.out.println("calling");
            i++;
        }
        System.out.println(webElement.getTagName());
        System.out.println("End");
        driver.close();
    }

    public static WebElement getWebElement(WebDriver driver, String id) {
        WebElement myDynamicElement = null;
        try {
            myDynamicElement = (new WebDriverWait(driver, 10))
                    .until(ExpectedConditions.presenceOfElementLocated(By
                            .id(id)));
            return myDynamicElement;
        } catch (TimeoutException ex) {
            return null;
        }
    }

0

Tôi đã thực thi một mã javascript để kiểm tra xem tài liệu đã sẵn sàng chưa. Tiết kiệm cho tôi rất nhiều thời gian gỡ lỗi kiểm tra selen cho các trang web có kết xuất phía máy khách.

public static boolean waitUntilDOMIsReady(WebDriver driver) {
def maxSeconds = DEFAULT_WAIT_SECONDS * 10
for (count in 1..maxSeconds) {
    Thread.sleep(100)
    def ready = isDOMReady(driver);
    if (ready) {
        break;
    }
}

}

public static boolean isDOMReady(WebDriver driver){
    return driver.executeScript("return document.readyState");
}

0
public boolean waitForElement(String zoneName, String element, int index, int timeout) {
        WebDriverWait wait = new WebDriverWait(appiumDriver, timeout/1000);
        wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(element)));
        return true;
    }

0

Giống như Rubanov đã viết cho C #, tôi viết nó cho Java và đó là:

    public void waitForPageLoaded() {
    ExpectedCondition<Boolean> expectation = new
            ExpectedCondition<Boolean>() {
                public Boolean apply(WebDriver driver) {
                    return (((JavascriptExecutor) driver).executeScript("return document.readyState").toString().equals("complete")&&((Boolean)((JavascriptExecutor)driver).executeScript("return jQuery.active == 0")));
                }
            };
    try {
        Thread.sleep(100);
        WebDriverWait waitForLoad = new WebDriverWait(driver, 30);
        waitForLoad.until(expectation);
    } catch (Throwable error) {
        Assert.fail("Timeout waiting for Page Load Request to complete.");
    }
}

0

Trong Java, nó sẽ như dưới đây: -

  private static boolean isloadComplete(WebDriver driver)
    {
        return ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("loaded")
                || ((JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete");
    }

1
Sẽ tốt hơn để kết hợp các lệnh JS thành một để bạn không cần phải nhấn trang hai lần, ví dụreturn document.readyState == 'loaded' || return document.readyState == 'complete'
JeffC

0

Các mã sau có thể hoạt động:

WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.presenceOfAllElementsLocated(By.xpath("//*")));

0

Nếu bạn có một trang chậm hoặc kết nối mạng, rất có thể không có cái nào ở trên sẽ hoạt động. Tôi đã thử tất cả chúng và điều duy nhất hiệu quả với tôi là chờ đợi phần tử hiển thị cuối cùng trên trang đó. Lấy ví dụ trang web Bing. Họ đã đặt biểu tượng CAMERA (tìm kiếm bằng nút hình ảnh) bên cạnh nút tìm kiếm chính chỉ hiển thị sau khi trang hoàn chỉnh được tải. Nếu mọi người đã làm điều đó, thì tất cả những gì chúng ta phải làm là sử dụng một sự chờ đợi rõ ràng như trong các ví dụ trên.


-1
public void waitForPageToLoad()
  {
(new WebDriverWait(driver, DEFAULT_WAIT_TIME)).until(new ExpectedCondition<Boolean>() {
      public Boolean apply(WebDriver d) {
        return (((org.openqa.selenium.JavascriptExecutor) driver).executeScript("return document.readyState").equals("complete"));
      }
    });//Here DEFAULT_WAIT_TIME is a integer correspond to wait time in seconds

-1

Đây là một cái gì đó tương tự, trong Ruby:

wait = Selenium::WebDriver::Wait.new(:timeout => 10)
wait.until { @driver.execute_script('return document.readyState').eql?('complete') }

Mã của bạn không làm việc cho tôi. Làm cách nào để chuyển đổi iframe và đợi onload = "javascript: pageload (); functionPageLoad ();" để tải lại trang trong Ruby? Tôi thấy mình mở iframe bên trong một trang, tôi có quyền truy cập vào nó, sau đó trang tải lại và tôi không thể truy cập vào khung nữa. Tôi đã đọc nhiều câu trả lời liên quan đến chờ đợi, ngủ, thời gian, chuyển sang khung hình sau đó đến cha mẹ, tuy nhiên tôi không thể đạt được mục tiêu của mình.
Amanda Cavallaro

1
Có vẻ như câu hỏi của bạn chủ yếu là về cách chuyển sang iFrame chứ không phải về việc chờ tải tài liệu. Có thể tốt hơn để bắt đầu một câu hỏi mới nếu bạn không thể tìm thấy giải pháp trong câu hỏi về cách làm việc với iFrames.
emery

-1

Bạn có thể có luồng ngủ cho đến khi trang được tải lại. Đây không phải là giải pháp tốt nhất, bởi vì bạn cần phải ước tính thời gian tải trang.

driver.get(homeUrl); 
Thread.sleep(5000);
driver.findElement(By.xpath("Your_Xpath_here")).sendKeys(userName);
driver.findElement(By.xpath("Your_Xpath_here")).sendKeys(passWord);
driver.findElement(By.xpath("Your_Xpath_here")).click();

Tôi thấy Thread.s ngủ (5000) thường là phương pháp duy nhất giúp thử nghiệm hoạt động, bất chấp mọi khuyến nghị không sử dụng. Không có sự kết hợp nào của việc chờ đợi phần tử hoạt động với tôi, đặc biệt là nhiều yếu tố không thể được xác định cho đến khi chúng thực sự được tìm thấy.
Steve Staple

-1

Tôi đã kiểm tra tải trang hoàn tất, hoạt động trong Selenium 3.14.0

    public static void UntilPageLoadComplete(IWebDriver driver, long timeoutInSeconds)
    {
        Until(driver, (d) =>
        {
            Boolean isPageLoaded = (Boolean)((IJavaScriptExecutor)driver).ExecuteScript("return document.readyState").Equals("complete");
            if (!isPageLoaded) Console.WriteLine("Document is loading");
            return isPageLoaded;
        }, timeoutInSeconds);
    }

    public static void Until(IWebDriver driver, Func<IWebDriver, Boolean> waitCondition, long timeoutInSeconds)
    {
        WebDriverWait webDriverWait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
        webDriverWait.Timeout = TimeSpan.FromSeconds(timeoutInSeconds);
        try
        {
            webDriverWait.Until(waitCondition);
        }
        catch (Exception e)
        {
            Console.WriteLine(e);
        }
    }

-1

Đối với những người cần chờ đợi một yếu tố cụ thể xuất hiện. (đã sử dụng c #)

public static void WaitForElement(IWebDriver driver, By element)
{
    WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(20));
    wait.Until(ExpectedConditions.ElementIsVisible(element));
}

Sau đó, nếu bạn muốn đợi ví dụ nếu một lớp = "thông báo lỗi" tồn tại trong DOM bạn chỉ cần làm:

WaitForElement(driver, By.ClassName("error-message"));

Đối với id, sau đó sẽ là

WaitForElement(driver, By.Id("yourid"));


-3

Bạn đang sử dụng Angular? Nếu bạn là có thể các webler không nhận ra rằng các cuộc gọi async đã kết thúc.

Tôi khuyên bạn nên nhìn vào Paul Hammants ngWebDriver . Phương thức WaitForAngularRequestsToFinish () có thể có ích.


Ông đã không sử dụng Angular rất nhiều. Câu trả lời này đã bị bỏ qua vì có vẻ như bạn không đọc kỹ câu hỏi ban đầu.
zelusp

Nhưng đừng bỏ phiếu làm bạn khó chịu. Mọi người ở đây có nghĩa là tốt. Và chỉ trích thực sự là một hình thức của tình yêu (bởi vì nếu ai đó dành thời gian để sửa chữa bất cứ ai thì đó là vì họ quan tâm). Kiểm tra Cách đặt câu hỏi theo cách thông minh - những ý tưởng đó cũng được áp dụng để trả lời câu hỏi theo cách thông minh.
zelusp
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.