Selenyum belge hazır olana kadar bekle


133

Biri bana nasıl selenyum sayfa tamamen yüklenene kadar bekletebilir miyim? Genel bir şey istiyorum, WebDriverWait'i yapılandırabileceğimi ve beklemesi için 'bul' gibi bir şey çağırabileceğimi biliyorum ama o kadar ileri gitmiyorum. Sadece sayfanın başarıyla yüklendiğini test etmem ve test etmek için bir sonraki sayfaya geçmem gerekiyor.

.Net'te bir şey buldum ama java'da çalışmasını sağlayamadım ...

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"));

Herhangi bir fikrin var mı?


Neden beklemeyi kullanmak istemiyorsun?
Amey

7
Açıkça beklemek mi demek istiyorsun? Zaman alıyor, 10.000 sayfayı test ediyorum.
Girish

2
Demek istediğim, çok sayıda bağlantıyı test ediyorsam bir düzeltme beklemesi eklemek iyi bir fikir olmayabilir, değil mi?
Girish

10
Sabit sayıda saniye beklemenin bir faydası yoktur. Bu tahmin.
Anders Lindén

Bir sayfanın javascript'inin herhangi bir genel kodu çalıştırabileceği düşünüldüğünde, tamamlanmasını beklemek için bir program yazmak imkansızdır. Bu, Duraklama Probleminin bir şeklidir ( en.wikipedia.org/wiki/Halting_problem ). Buradaki herhangi bir çözümün ödün vermesi veya temeldeki web sayfasının varsayımlarına dayanması gerekecektir.
2016

Yanıtlar:


83

Bu kodu deneyin:

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

Yukarıdaki kod, sayfanın yüklenmesi için 10 saniyeye kadar bekleyecektir. Sayfa yükleme süresi aşarsa TimeoutException,. İstisnayı yakalar ve ihtiyaçlarınızı yerine getirirsiniz. İstisna atıldıktan sonra sayfa yüklemeden çıkıp çıkmayacağından emin değilim. bu kodu henüz denemedim. Sadece denemek istiyorum.

Bu örtük bir beklemedir. Bunu bir kez ayarlarsanız, Web Sürücüsü örneği yok olana kadar kapsama sahip olur.

Daha fazla bilgi için belgelereWebDriver.Timeouts bakın .


3
Teşekkürler, bu durumda sayfa 10 saniyeden önce yüklenirse, yüklendikten sonra bir sonraki satırı çalıştırmak için yine de 10 saniye bekler mi?
Girish

Hayır, sayfanız 10 saniyeden önce yüklenirse, bekleme koşulunu sonlandıracağı ve önceki satırı çalıştıracağı anlamına gelir.
Manigandan

3
Bu, zaman aşımına uğraması ve istisnalar atması çok uzun süren sayfa yüklemeleri beklediğinizde kullanılır, bir sayfanın yüklenmesini hemen beklemez veya daha iyi bir yükleme politikası belirlemez. Varsayılan olarak sonsuz zamana ayarlıdır, bu nedenle sayfanız yüklenirken hiçbir zaman istisna oluşturmaz ve Selenium her zaman bunların tamamen yüklenmesini beklemeye çalışır.
Petr Janeček

19
Bu yöntemle ilgili sorun, örtük bekleme önceden başarıyla bir WebElement nesnesi döndürmesine rağmen DOM'un tamamen erişilebilir olmamasıdır. Ardından, öğeyi tıklatmaya çalışırsanız, eski bir öğe istisnası alırsınız. Yani, bu cevap tamamen güvenli değil.
djangofan

3
Bu zaman aşımı, bir belgenin yüklenmesini beklemeyle nasıl ilişkilidir?
Anders Lindén

90

Sizin Önerilen çözüm sadece bekler DOMreadyState sinyaline complete. Ancak Selenium varsayılan olarak sayfa yüklemelerinde bunları (ve biraz daha fazlasını) driver.get()veelement.click() yöntemleri . Zaten engelliyorlar, sayfanın tamamen yüklenmesini bekliyorlar ve bunların düzgün çalışması gerekiyor.

Açıkçası sorun, AJAX istekleri ve çalışan komut dosyaları aracılığıyla yönlendirmelerdir - bunlar Selenium tarafından yakalanamaz, bitmelerini beklemez. Ayrıca, onları güvenilir bir şekilde yakalayamazsınız readyState- biraz bekler, bu yararlı olabilir, ancak completetüm AJAX içeriği indirilmeden çok önce sinyal verecektir .

Her yerde ve herkes için işe yarayacak genel bir çözüm yok, bu yüzden zor ve herkes biraz farklı bir şey kullanıyor.

Genel kural, üzerine düşeni yapması için WebDriver'a güvenmek, ardından örtük beklemeler kullanmak, ardından sayfada öne sürmek istediğiniz öğeler için açık beklemeler kullanmaktır, ancak yapılabilecek çok daha fazla teknik vardır. Sizin durumunuza en uygun olanı (veya birkaçının bir kombinasyonunu) test ettiğiniz sayfadan seçmelisiniz.

Daha fazla bilgi için bununla ilgili iki cevabıma bakın:


20
Bu yanlış, Selenium element.click()aramaları beklemez veya engellemez .
hwjp

3
@hwjp Daha fazlasını detaylandırmak ister misiniz? JavaDocs aksini söylüyor : "Bu, yeni bir sayfanın yüklenmesine neden olursa, bu yöntem sayfa yüklenene kadar engellemeyi deneyecektir."
Petr Janeček

5
e-posta listesinde yaptığım bazı konuşmalarsa , bu yanlış görünüyor. selenium, açıkça bir URL talep ettiğiniz .get çağrılarını engelleyebilir, ancak tıklama çağrılarında özel bir şey yapmaz, çünkü "gerçek" bir köprüyü veya javascript tarafından durdurulacak bir köprüyü tıklayıp tıklamadığınızı söyleyemez. ..
hwjp

4
Posta listesi tartışmasının başında bir hataya bağlantı veriyorum. Dokümanlar bile şüpheli: "Click () [...] yerel bir olay gönderilerek yapılırsa, yöntem * beklemeyecektir *"
hwjp

4
Bu nedenle, tarayıcının "yerel olayları" kullanıp kullanmadığı açılır. Görünüşe göre çoğu varsayılan olarak: code.google.com/p/selenium/wiki/… (bu yüzden bu belgelerin en iyi ihtimalle yanıltıcı olduğunu söyleyebilirim. Posta listesine ping atacaktır).
hwjp

61

Bu, verdiğiniz örneğin çalışan bir Java sürümüdür:

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

C # Örneği:

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
Dostum, bunu kopyalayıp yapıştırıyorum. Bu pasaj sadece harika. Bunu neden düşünmedim? Gerçek şu ki, birden fazla göz küresi her zaman iyi bir çözüme yol açar. Teşekkürler.
luis.espinal

2
Bunu, lambda ifadeleri desteklemediğinden java 1.7 sürümüne uyumlu hale getirebilir misiniz
vkrams

3
Java 1.7 sürümü: wait.until (yeni Predicate <WebDriver> () {public boolean apply (WebDriver sürücüsü) {return ((JavascriptExecutor) sürücüsü) .executeScript ("return document.readyState"). Equals ("complete");} });
luQ

1
Birisi çözümü @IuQ ile kullanmak isterse, o zaman Predicate içe import com.google.common.base.Predicate
aktarır

Bu fikri bir VB test uygulamasında denedim. Çoğu zaman işe yarar. Bazen bu hatayı alıyorum: System.InvalidOperationException: OpenQA.Selenium.Remote.RemoteWebDriver.UnpackAndThrowOnError'da JavaScript hatası (UnexpectedJavaScriptError) (Response errorResponse) Test uygulaması 2. düzey menü bağlantısına tıklar, ardından WaitObj.Until (Function (D) DirectC D, InternetExplorerDriver) .ExecuteScript ("return document.readyState") = "tamamlandı"). Sanırım hata, tarayıcının geçerli sayfayı kaldırması ve belge nesnesi olmaması nedeniyle ortaya çıkıyor. "Return document.readystate? Fikirler?
CoolBreeze

12

İşte Python'da tamamen genel bir çözüme yönelik girişimim:

İlk olarak, genel bir "bekle" işlevi (isterseniz bir WebDriverWait kullanın, onları çirkin buluyorum):

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__))

Daha sonra çözüm, selenyumun üst düzey <html>öğe de dahil olmak üzere bir sayfadaki tüm öğeler için bir (dahili) kimlik numarası kaydetmesine dayanır . Bir sayfa yenilendiğinde veya yüklendiğinde, yeni bir kimliğe sahip yeni bir html öğesi alır.

Dolayısıyla, "bağlantım" metni içeren bir bağlantıya tıklamak istediğinizi varsayarsak, örneğin:

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)

Daha fazla Pythonic, yeniden kullanılabilir, genel bir yardımcı için bir bağlam yöneticisi yapabilirsiniz:

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)

Ve sonra hemen hemen her selenyum etkileşiminde kullanabilirsiniz:

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

Sanırım bu kurşun geçirmez! Ne düşünüyorsun?

Bununla ilgili bir blog gönderisinde daha fazla bilgi burada


Çok ilginç bir yaklaşım. Bir zorluk, bunun tarayıcı ilk başlatıldıktan sonra ilk sayfa yüklemesinde çalışıp çalışamayacağıdır. Tarayıcının ilk durumunun herhangi bir sayfanın yüklü olduğuna dair bir garanti yoktur. Ayrıca Java'da, nesnede bir 'id' olduğunu görmüyorum - selenyumun bir html id niteliği eklediğini kastetmediğinizi varsayıyorum. Bu seçeneği daha fazla keşfettikten sonra bu yanıta daha fazlasını ekleyeceğim. Gönderi için teşekkürler!
Lukus

@hwjp Bu çözümü birçok kez mükemmel sonuçlarla kullanıyorum, ancak tek bir durumda işe yaramıyor gibi görünüyor. Sorunun tam açıklaması stackoverflow.com/q/31985739/4249707
El Ruso

7

Benzer bir problemim vardı. Belgem hazır olana kadar beklemem gerekiyordu, aynı zamanda tüm Ajax çağrıları bitene kadar. İkinci durumun tespit edilmesi zor oldu. Sonunda aktif Ajax çağrılarını kontrol ettim ve işe yaradı.

JavaScript:

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

Tam C # yöntemi:

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);
}

document.readyState == 'complete' && jQuery.active == 0React gibi bir şey var mı ?
Rain9333

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

4

C # NUnit için, WebDriver'ı JSExecuter'a dönüştürmeniz ve ardından document.ready durumunun tamamlanıp tamamlanmadığını kontrol etmek için komut dosyasını çalıştırmanız gerekir. Referans için aşağıdaki kodu kontrol edin:

 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");
    }

Bu, koşul karşılanana veya zaman aşımına uğrayana kadar bekleyecektir.


3

İlk sayfa yüklemesi için, tarayıcı penceresini "Büyütme" nin pratik olarak sayfa yüklemesi tamamlanana kadar beklediğini fark ettim (kaynaklar dahil)

Değiştir:

AppDriver.Navigate().GoToUrl(url);

İle:

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;
                }
            }

kullanmaktan:

OpenURL(myDriver, myUrl);

Bu, sayfayı yükleyecek, tamamlanana kadar bekleyecek, ekranı kaplayacak ve odaklanacaktır. Neden böyle bilmiyorum ama işe yarıyor.

Bir sonraki tıkladıktan sonra sayfanın yüklenmesini veya "Navigate ()" dışında başka herhangi bir sayfa gezinme tetikleyicisini beklemek istiyorsanız, Ben Dyer'in cevabı (bu başlıkta) işi yapacaktır.


1

Goblen web çerçevesine bir göz atın . Kaynak kodunu buradan indirebilirsiniz .

Buradaki fikir, body'nin html niteliği ile sayfanın hazır olduğunu belirtmektir. Bu fikri kullanarak karmaşık davaları görmezden gelebilirsiniz.

<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>

Ve sonra Selenium webdriver uzantısını oluşturun (goblen çerçevesine göre)

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
    }          
}

Alister Scott tarafından yazılmış olan ElementIsDisplayed uzantısını kullanın .

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

Ve son olarak test oluşturun:

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

1

Ben Dryer'in cevabı makinemde ( "The method until(Predicate<WebDriver>) is ambiguous for the type WebDriverWait") derlenmedi .

Çalışan Java 8 sürümü:

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

Java 7 sürümü:

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

Bu kodu denedim ve benim için çalışıyor. Başka bir sayfaya her geçtiğimde bu işlevi çağırıyorum

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

Nodejs'de sözler yoluyla alabilirsiniz ...

Bu kodu yazarsanız, o zamana geldiğinizde sayfanın tamamen yüklendiğinden emin olabilirsiniz ...

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

Bu kodu yazarsan seyreden, selenyum 3 saniye bekleyecek ...

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...

Selenium belgelerinden:

this.get (url) → Ödenebilir

Verilen URL'ye gitmek için bir komut zamanlar.

Belgenin yüklenmesi tamamlandığında çözülecek bir söz verir .

Selenyum Belgeleri (Nodejs)


1

Document.ready olayı bekle, bu sorunun tam çözümü değildir, çünkü bu kod hala bir yarış durumundadır: Bazen bu kod, click olayı işlenmeden önce çalıştırılır, bu nedenle tarayıcı başlatılmadığından bu doğrudan geri döner. henüz yeni sayfa yükleniyor.

Biraz araştırdıktan sonra , bu soruna bir çözümü olan test keçisi Obay'da bir yazı buldum . Bu çözümün c # kodu şuna benzer:

 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"));

}

`Bu yöntemi doğrudan driver.navigate.gotourl'den sonra çalıştırıyorum, böylece mümkün olan en kısa sürede sayfanın referansını alabilsin. Onunla iyi eğlenceler!


1

Normalde selenyum bir tıklama veya gönderme veya alma yöntemlerinden yeni bir sayfa açtığında, sayfanın yüklenmesini bekler, ancak sorun, sayfanın bir xhr çağrısı (ajax) olduğunda, xhr'nin yüklenmesini asla beklemeyeceğidir. xhr'yi izlemek ve onları beklemek için yeni bir yöntem yaratmak iyi olacaktır.

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 == 0bu nedenle aktif xhrs çağrısı yoktur (sadece jQuery ile çalışır). javascript ajax çağrısı için projenizde bir değişken oluşturmalı ve onu simüle etmelisiniz.


0

Bunu halletmek için biraz mantık yazabilirsiniz. 'I döndürecek bir yöntem yazdım WebElementve bu yöntem üç kez çağrılacak veya zamanı artırıp boş bir kontrol ekleyebilirsiniz WebElementİşte bir örnek

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

Belgenin hazır olup olmadığını kontrol etmek için bir javascript kodu çalıştırdım. İstemci tarafında oluşturmaya sahip siteler için selenyum testlerinde hata ayıklama konusunda bana çok zaman kazandırdı.

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

Rubanov'un C # için yazdığı gibi, onu Java için yazıyorum ve şu:

    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

Java'da aşağıdaki gibi olacaktır: -

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

1
JS komutlarını tek bir sayfada birleştirmek daha iyi olur, böylece sayfaya iki kez return document.readyState == 'loaded' || return document.readyState == 'complete'
basmak zorunda kalmazsınız

0

Aşağıdaki kod muhtemelen çalışmalıdır:

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

0

Yavaş bir sayfanız veya ağ bağlantınız varsa, yukarıdakilerin hiçbiri işe yaramayacaktır. Hepsini denedim ve benim için işe yarayan tek şey o sayfadaki son görünür öğeyi beklemekti. Örneğin Bing web sayfasını ele alalım. Ana arama düğmesinin yanına, yalnızca sayfanın tamamı yüklendikten sonra görülebilen bir KAMERA simgesi (resimle arama düğmesi) yerleştirmişlerdir. Herkes bunu yaptıysa, tek yapmamız gereken yukarıdaki örneklerde olduğu gibi açık bir bekleme kullanmaktır.


-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

İşte Ruby'de benzer bir şey:

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

Kodunuz benim için çalışmıyor. Do iframe'i nasıl değiştiririm ve onload = "javascript: pageload (); functionPageLoad ();" Ruby'de sayfayı yeniden yüklemek için? Kendimi bir sayfanın içinde iframe'i açarken buluyorum, ona erişimim var, sonra sayfa yeniden yükleniyor ve artık çerçeveye erişemiyorum. Bekle, uyku, zaman, çerçeveye geç ve sonra ebeveyn ile ilgili birçok cevap okudum, ancak hedefime ulaşamıyorum.
Amanda Cavallaro

1
Görünüşe göre sorunuz belgenin yüklenmesini beklemekle değil, iFrame'e nasıl geçeceğinizle ilgili. İFrame'lerle çalışma hakkındaki bir soruda çözümü bulamazsanız yeni bir soru sormaya başlamak daha iyi olabilir.
emery

-1

Sayfa yeniden yüklenene kadar iş parçacığını uyutabilirsiniz. Bu en iyi çözüm değildir, çünkü sayfanın yüklenmesinin ne kadar süreceği konusunda bir tahminde bulunmanız gerekir.

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();

Thread.sleep (5000), kullanmayla ilgili tüm tavsiyelere rağmen, genellikle bir testi çalıştıran tek yöntemdir. Eleman için beklemenin hiçbir kombinasyonu benim için işe yaramaz, özellikle de gerçekten bulunana kadar birçok öğe tanımlanamayacağından.
Steve Staple

-1

Sayfa yüklemesinin tamamlandığını kontrol ettim, Selenium 3.14.0'da çalıştım

    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

Belirli bir unsurun ortaya çıkmasını beklemesi gereken insanlar için. (kullanılan c #)

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

Daha sonra, örneğin DOM'da bir class = "error-message" varsa, beklemek isterseniz, yapmanız gereken:

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

İd için, o zaman olacaktır

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


-3

Angular kullanıyor musunuz? Eğer öyleyseniz, web sürücüsünün eşzamansız çağrıların bittiğini fark etmemesi mümkündür.

Paul Hammants ngWebDriver'a bakmanızı tavsiye ederim . WaitForAngularRequestsToFinish () yöntemi kullanışlı olabilir.


Angular'ı pek kullanmıyordu. Bu yanıt, orijinal soruyu dikkatlice okumamış göründüğünüz için reddedildi.
zelusp

Ama oyların sizi şekilden alıkoymasına izin vermeyin. Buradaki insanlar iyi niyetli. Ve eleştiri aslında bir aşk biçimidir (çünkü eğer birisi birini düzeltmek için zaman ayırıyorsa, bunun sebebi önemsiyor olmasıdır). Çıkış Akıllıca soru sorma - bu fikirler aynı zamanda soruları akıllıca yanıtlamak için de geçerlidir.
zelusp
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.