Selenium Webdriver/ c# -如何在点击后确认页面加载

本文关键字:确认 加载 Webdriver Selenium | 更新日期: 2023-09-27 18:15:18

我试图调用的网站基本上使用。ascx和aspx页面来呈现他们的项目。为了导航,你必须使用click事件而不是goto url。目前我正在使用Thread.Sleep(3000),但这很笨拙,我认为这不是最好的方法。

为了确保页面已经从click事件加载,你可以添加什么?

IWebElement myLink;
myLink = driver.FindElement(By.Id("ctl00_ctl00_cphContentArea_cphContentArea_ucwaag_lnkbtnDate" + i.ToString()));
myLink.Click();
Thread.Sleep(5000); //yeah need to fix this

Selenium Webdriver/ c# -如何在点击后确认页面加载

这是我们在尝试使用Selenium时遇到的完全相同的问题。

我们通过使用等待条件解决了这个问题。

wait.Until(ExpectedConditions.ElementExists(locator));
wait.Until(ExpectedConditions.ElementIsVisible(locator));

我们必须同时使用ElementExists和ElementIsVisible来解决控件在页面上但还不可见的问题

您最好等待目标页面上的已知元素出现-引入任何睡眠语句都会使您的测试非常脆弱,因此您应该尽量避免这种情况。

所以像这样:

wait.Until(d => d.FindElement(By.Id(someId)));
在这种情况下,你可能会发现这个Stackoverflow问题很有用。

我不确定这种方法是否正确,但我正在使用池机制,等待javascript变量设置,当页面完全加载时手动设置(因为没有办法告诉它何时实际完成)。

c#

public void WaitUntilLoaded()
    {
        Func<IWebDriver, bool> test = drv =>
        {
          result = (bool?)js.ExecuteScript("return SeleniumHelper.isPageLoaded;");
        };
        TestHelper.WaitUntil(this.Driver, d => { }, test, Constants.Pause.Medium, "load", logWaitTime: true);
    }
internal static class TestHelper
   {
   private static readonly string StartDateString = DateTime.Now.ToString("yyyy-MM-ddTHH-mm-ss");
   private static readonly Random Rnd = new Random((int)DateTime.Now.Ticks);
   public static void WaitUntil(IWebDriver driver, Action<IWebDriver> action, Func<IWebDriver, bool> predicate, TimeSpan timeOut, string waitingForDescription, bool logWaitTime = false)
   {
       action(driver);
       int retryCount = 0;
       var now = DateTime.Now;
       var wait = new WebDriverWait(driver, timeOut);
       Func<IWebDriver, bool> fullPredicate = drv =>
       {
           var res = predicate(drv);
           if (!res)
               {
               bool hasErr = IsShowingErrorLoadingPage(drv);
               if (hasErr)
               {
                   Console.WriteLine(string.Format("Page is marked with [{0}]", "Error Loading Page"));
                   if (retryCount++ == 0)
                   {
                        Console.WriteLine("Retrying...");
                        action(driver);
                        res = false;
                   }
                }
            }
            return res;
        };
        try
        {
            wait.Until(fullPredicate);
        }
        catch (TimeoutException)
        {
            string waitMsg = timeOut.TotalSeconds >= 1 ? (timeOut.TotalSeconds + "s") : (timeOut.TotalMilliseconds + "ms");
            throw new TimeoutException(string.Format("Waited for {0} to {1} without success [{2}].", waitMsg, waitingForDescription, WritePageSource(driver)));
        }
        if (logWaitTime)
        {
            Console.WriteLine("WaitUntil: Requested wait: " + Math.Round(timeOut.TotalSeconds, 2).ToString("0.00").PadLeft(5, ' ') + "s; actual wait: " + Math.Round(DateTime.Now.Subtract(now).TotalSeconds, 3).ToString("0.000").PadLeft(6, ' ') + "s");
        }
  }
 public static bool IsStale(IWebElement element)
 {
     return Throws<StaleElementReferenceException>(() => element.GetAttribute("x"));
 }
 public static bool IsShowingErrorLoadingPage(IWebDriver driver)
 {
        IWebElement failedToLoad;
        try
        {
            failedToLoad = driver.FindElements(By.TagName("h1")).Where(el => el.Text == "Error Loading Page").FirstOrDefault();
        }
        catch (StaleElementReferenceException)
        {
            failedToLoad = null;
        }
        return failedToLoad != null;
    }
}
Javascript:

 function SeleniumHelper() {
    isPageLoaded = false;
    this.markPageAsLoaded = function () {
        logger.log('page marked as loaded');
        isPageLoaded = true;
    };
}