4

我已經在C#中啓動了一個Selenium項目。試圖等待頁面完成加載,然後才能繼續下一個操作。如何讓webDriver等待頁面加載(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; 
    } 

你會如何解決這個障礙?

回答

5

我一直在尋找替代品和我已經解決了以下版本。全部使用明確的等待和定義的超時,並且基於第一種情況下的元素屬性和第二種情況下的元素過期。

首選將檢查元素屬性,直到達到超時。我已到達以下屬性,確認它在頁面上可用:

存在 - 期望檢查頁面的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(元素)是有用的,其中元素是單擊的項目以觸發重定向到新頁面。

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

優秀徹底的答案! 有沒有辦法等待彈出窗口加載? – Lars

1

我通常使用一個明確的等待這個,並等待,直到一個元素是可見的,然後進行下一個動作。這應該是這樣的:

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

更多明確的等待在這裏:Explicit waits Selenium C#這裏WebDriver Explicit waits

4

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

而且,看this answer

相關問題