2011-08-31 60 views
4

我發現嘗試使用Selenium WebDriver測試我們的應用程序時出現問題。這個問題出現在IE9的不穩定彈出窗口中。它不總是可重複的,它發生在大約20%的窗口切換中,但是使得對IE的測試幾乎不可能。在FireFox中,一切都很完美。Internet Explorer中的Selenium WebDriver窗口切換問題8-10

  1. 我嘗試增加超時:

TimeSpan interval = new TimeSpan(0, 0, 10); driver.Manage().Timeouts().ImplicitlyWait(interval);

  1. 創建對象自己的方法發現:

      for (int x = 0; x <= waitTimeOut; x++) 
          { 
           try 
           { 
            element = (IWebElement)driver.FindElement(By.XPath(obj.Xpath)); 
            return element; 
           } 
    
           catch{} 
          } 
    
  2. 嘗試使用CssSelecotrs

  3. 嘗試做一些再轉換尋找元素之前:

    driver.SwitchTo().Window(GetWindowHandle(2, 1)); driver.SwitchTo().Window(GetWindowHandle(0, 1)); driver.SwitchTo().Window(GetWindowHandle(2, 1));

如果出現問題,它總是隻有我嘗試在網頁上找到的第一個元素出現。如果找到該元素,則在此頁面上查找其他元素沒有任何問題。所以我決定把重點放在問題上。

調試器中的Windows句柄正確顯示。例如,如果我切換到第三個窗口,driver.CurrentWindowHandle給了我第三個窗口的正確句柄。但是如果我試圖找到任何元素,FindElement()會引發一個異常。該頁面已加載,我可以手動單擊該元素,但FindElement()找不到它。如果我重新運行測試,這個步驟可以毫無問題地通過,並且只在下次切換或更進一步失敗。這是不可預測的。

這種問題的原因是什麼?

+0

您使用的是哪個版本的Selenium?我以前只有一個類似的問題,我必須通過在SwitchTo命令後添加一個1000-5000ms的休眠解決方案。 – prestomanifesto

回答

11

使用IE驅動程序時,無法保證窗口在集合中的顯示順序。也就是說,集合中的第0個窗口不一定是會話打開的第一個窗口。鑑於這樣的話,你需要做一些這樣的:

private string FindNewWindowHandle(IWebDriver driver, IList<string> existingHandles, int timeout) 
{ 
    string foundHandle = string.Empty; 
    DateTime endTime = DateTime.Now.Add(TimeSpan.FromSeconds(timeout)); 
    while (string.IsNullOrEmpty(foundHandle) && DateTime.Now < endTime) 
    { 
     IList<string> currentHandles = driver.WindowHandles; 
     if (currentHandles.Count != existingHandles.Count) 
     { 
      foreach (string currentHandle in currentHandles) 
      { 
       if (!existingHandles.Contains(currentHandle)) 
       { 
        foundHandle = currentHandle; 
        break; 
       } 
      } 
     } 

     if (string.IsNullOrEmpty(foundHandle)) 
     { 
      System.Threading.Thread.Sleep(250); 
     } 
    } 

    // Note: could optionally check for handle found here and throw 
    // an exception if no window was found. 
    return foundHandle; 
} 

上述函數的用法是類似以下內容:

IList<string> handles = driver.WindowHandles; 
// do whatever you have to do to invoke the popup 
element.Click(); 
string popupHandle = FindNewWindowHandle(driver, handles, 10); 
if (!string.IsNullOrEmpty(popupHandle)) 
{ 
    driver.SwitchTo().Window(popupHandle); 
} 
+0

謝謝,我將它轉換爲Java,併爲我工作。你真棒。 – djangofan

+0

隨時提供答案。 :) – JimEvans

+0

這解釋了一些事情......我一直在基於索引切換IE,假設窗口句柄將按照它們打開的順序。 – PocketDews

0
String currentWindowHandle = driver.getWindowHandle(); 
     driver.findElement(By.cssSelector(locator)).click(); 
     Set<String> windows = driver.getWindowHandles(); 
     for (String window : windows) { 
      if (!window.equals(currentWindowHandle)) { 
       driver.switchTo().window(window); 
       driver.close(); 
      } 
     } 
     driver.switchTo().window(currentWindowHandle); 
+0

你應該解釋你的答案。 – sparkyShorts

1

如果是IE11,修改HKLM_CURRENT_USER \ Software \ Microsoft \ Internet Explorer \ Main路徑應該包含具有0值的關鍵TabProcGrowth。

相關問題