如何让webDriver等待页面加载(C#Selenium项目)

我在C#开始了一个Selenium项目。 尝试等待页面完成加载,然后才进行下一步操作。

我的代码如下所示:

loginPage.GoToLoginPage(); loginPage.LoginAs(TestCase.Username, TestCase.Password); loginPage.SelectRole(TestCase.Orgunit); loginPage.AcceptRole(); 

在loginPage.SelectRole(TestCase.Orgunit)中:

  RoleHierachyLabel = CommonsBasePage.Driver.FindElement(By.XPath("//span[contains(text(), " + role + ")]")); RoleHierachyLabel.Click(); RoleLoginButton.Click(); 

我搜索元素RoleHierachyLabel。 我一直在尝试使用多种方式等待页面加载或搜索允许一些超时的元素属性:

 1. _browserInstance.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(5)); 

 2. public static bool WaitUntilElementIsPresent(RemoteWebDriver driver, By by, int timeout = 5) { for (var i = 0; i < timeout; i++) { if (driver.ElementExists(by)) return true; } return false; } 

你会如何解决这个障碍?

我一直在寻找替代品,我已经选择了以下版本。 所有都使用显式等待和定义的超时,并且基于第一种情况下的元素属性和第二种情况下的元素陈旧性。

首选是检查元素属性,直到达到超时。 我已经到达以下属性,确认它在页面上可用:

存在 – 期望检查页面的DOM上是否存在元素。 这并不一定意味着该元素是可见的。

 //this will not wait for page to load Assert.True(Driver.FindElement(By elementLocator).Enabled) //this will search for the element until a timeout is reached public static IWebElement WaitUntilElementExists(By elementLocator, int timeout = 10) { try { var wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(timeout)); return wait.Until(ExpectedConditions.ElementExists(elementLocator)); } catch (NoSuchElementException) { Console.WriteLine("Element with locator: '" + elementLocator + "' was not found in current context page."); throw; } } 

可见性 – 期望检查页面的DOM上是否存在元素并且可见。 可见性意味着元素不仅会显示,而且高度和宽度也会大于0。

 //this will not wait for page to load Assert.True(Driver.FindElement(By elementLocator).Displayed) //this will search for the element until a timeout is reached public static IWebElement WaitUntilElementVisible(By elementLocator, int timeout = 10) { try { var wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(timeout)); return wait.Until(ExpectedConditions.ElementIsVisible(elementLocator)); } catch (NoSuchElementException) { Console.WriteLine("Element with locator: '" + elementLocator + "' was not found."); throw; } } 

可点击 – 可以看到并启用检查元素的期望,以便您可以单击它。

 //this will not wait for page to load //both properties need to be true in order for element to be clickable Assert.True(Driver.FindElement(By elementLocator).Enabled) Assert.True(Driver.FindElement(By elementLocator).Displayed) //this will search for the element until a timeout is reached public static IWebElement WaitUntilElementClickable(By elementLocator, int timeout = 10) { try { var wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(timeout)); return wait.Until(ExpectedConditions.ElementToBeClickable(elementLocator)); } catch (NoSuchElementException) { Console.WriteLine("Element with locator: '" + elementLocator + "' was not found in current context page."); throw; } } 

当触发对象(例如菜单项)在单击后不再附加到DOM时,将应用第二个选项 。 通常情况下,元素上的单击操作将触发重定向到另一个页面。 在这种情况下, 检查StalenessOf(element)是有用的,其中element是被单击以触发重定向到新页面的项目。

 public static void ClickAndWaitForPageToLoad(By elementLocator, int timeout = 10) { try { var wait = new WebDriverWait(Driver, TimeSpan.FromSeconds(timeout)); var element = Driver.FindElement(elementLocator); element.Click(); wait.Until(ExpectedConditions.StalenessOf(element)); } catch (NoSuchElementException) { Console.WriteLine("Element with locator: '" + elementLocator + "' was not found in current context page."); throw; } } 

driver.Manage().Timeouts().PageLoad = TimeSpan.FromSeconds(5);

另外,请看这个答案

我通常使用显式等待,并等待元素可见,然后继续下一个操作。 这应该是这样的:

 WebDriverWait waitForElement = new WebDriverWait(driver, TimeSpan.FromSeconds(5)); waitForElement.Until(ExpectedConditions.ElementIsVisible(By.Id("yourIDHere"))); 

更多关于显式等待: 显式等待Selenium C#和这里WebDriver显式等待

我这样做是为了解决这类问题。 它是定时器和循环的组合,它们寻找特定元素,直到它在一定的毫秒数后超时。

 private IWebElement FindElementById(string id, int timeout = 1000) { IWebElement element = null; var s = new Stopwatch(); s.Start(); while (s.Elapsed < TimeSpan.FromMilliseconds(timeout)) { try { element = _driver.FindElementById(id); break; } catch (NoSuchElementException) { } } s.Stop(); return element; } 

我也为元素启用了一个

 private IWebElement ElementEnabled(IWebElement element, int timeout = 1000) { var s = new Stopwatch(); s.Start(); while (s.Elapsed < TimeSpan.FromMilliseconds(timeout)) { if (element.Enabled) { return element; } } s.Stop(); return null; }