2014-12-22 9 views
8

Pracuję z selox firefox webdrivers w C# winform i mam ten kod poniżej, aby uzyskać uchwyt popup, który pokazuje po kliknięciu na "webtraffic_popup_start_button" i powinien dostać uchwyt popup, ale uchwyt popup jest taki sam jak obecny.popup's w selenowych webdrivers

string current = driver.CurrentWindowHandle; 
driver.FindElement(By.XPath("//*[@id='webtraffic_popup_start_button']")).Click(); 
Thread.Sleep(Sleep_Seconds); 
popup = driver.CurrentWindowHandle; 
Thread.Sleep(3000); 
driver.SwitchTo().Window(current); 
Thread.Sleep(1000); 

Każda pomoc z tym byłoby bardzo doceniane dziękuję

To właśnie pop-up wygląda.

Popup_Image

+0

Proszę wyjaśnić aktualne. Czy masz na myśli okno nadrzędne? Czy jest jeszcze inny pop-up? – Saifur

+0

Nie wiem, sprawdź zrzut ekranu, postawiłem – Coderz

Odpowiedz

20

WebDriver ma absolutnie żadnego śledzenia ogóle wykryć które okno znajduje się na pierwszym planie w systemie operacyjnym i nie dokonuje automatycznego przełączania whe n nowe okna przeglądarki są otwarte. Oznacza to, że właściwym sposobem uzyskania uchwytu nowo otwartego okna jest proces wieloetapowy. Aby to zrobić, należy:

  1. Zapisz aktualnie nakierowany uchwyt okna na zmienną, aby mógł się z niego później przełączyć.
  2. Wyświetl listę aktualnie otwartych uchwytów okien.
  3. Wykonaj czynność, która spowodowałaby pojawienie się nowego okna.
  4. Poczekaj na zwiększenie liczby uchwytów okien o 1.
  5. Pobierz nową listę klamek okiennych.
  6. Znajdź nowy uchwyt na liście uchwytów.
  7. Przełącz na to nowe okno.

W kodzie za pomocą powiązań językowych .NET, który będzie wyglądał tak:

string currentHandle = driver.CurrentWindowHandle; 
ReadOnlyCollection<string> originalHandles = driver.WindowHandles; 

// Cause the popup to appear 
driver.FindElement(By.XPath("//*[@id='webtraffic_popup_start_button']")).Click(); 

// WebDriverWait.Until<T> waits until the delegate returns 
// a non-null value for object types. We can leverage this 
// behavior to return the popup window handle. 
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5)); 
string popupWindowHandle = wait.Until<string>((d) => 
{ 
    string foundHandle = null; 

    // Subtract out the list of known handles. In the case of a single 
    // popup, the newHandles list will only have one value. 
    List<string> newHandles = driver.WindowHandles.Except(originalHandles).ToList(); 
    if (newHandles.Count > 0) 
    { 
     foundHandle = newHandles[0]; 
    } 

    return foundHandle; 
}); 

driver.SwitchTo().Window(popupWindowHandle); 

// Do whatever you need to on the popup browser, then... 
driver.Close(); 
driver.SwitchToWindow(currentHandle); 

Ewentualnie, jeśli używasz powiązań .NET, tam PopupWindowFinder klasa w WebDriver.Support zestaw, który został specjalnie zaprojektowany do wykonywania tych operacji. Używanie tej klasy jest znacznie prostsze.

// Get the current window handle so you can switch back later. 
string currentHandle = driver.CurrentWindowHandle; 

// Find the element that triggers the popup when clicked on. 
IWebElement element = driver.FindElement(By.XPath("//*[@id='webtraffic_popup_start_button']")); 

// The Click method of the PopupWindowFinder class will click 
// the desired element, wait for the popup to appear, and return 
// the window handle to the popped-up browser window. Note that 
// you still need to switch to the window to manipulate the page 
// displayed by the popup window. 
PopupWindowFinder finder = new PopupWindowFinder(driver); 
string popupWindowHandle = finder.Click(element); 

driver.SwitchTo().Window(popupWindowHandle); 

// Do whatever you need to on the popup browser, then... 
driver.Close(); 
driver.SwitchToWindow(currentHandle); 
+1

nieobsługiwany wyjątek typu „OpenQA.Selenium.WebDriverTimeoutException” wystąpił w WebDriver.Support.dll Informacje dodatkowe: limit czasu po upływie 5 sekund – Coderz

+0

myślę, że to się stało, bo kiedy się pojawi to już przednie okno. – Coderz

+0

To działało trochę, ale nie mogę nie używać sterownika po użyciu sterownika.Close(); – Coderz

3

Jeżeli wreszcie otworzył okno ma swój cel, a następnie po prostu wykonaj następujące czynności po kliknięciu

driver.SwitchTo().Window(driver.WindowHandles.ToList().Last()); 

EDIT

//You may need to go back to parent window to perform additional actions; 

// to the new window 
driver.SwitchTo().Window(driver.WindowHandles.ToList().Last()); 

// to the new window 
driver.SwitchTo().Window(driver.WindowHandles.ToList().First()); 
//or 
driver.SwitchTo().DefaultContent(); 
+1

Lista zwrócona przez właściwość 'WindowHandles' jest jawnie nieuporządkowana. Nie ma gwarancji, że uchwyt nowo otwartego okna będzie ostatnim na liście i nie ma gwarancji, że pierwsze okno przeglądarki będzie pierwszym na liście. Dodatkowo 'DefaultContent' przełącza się tylko na ramkę najwyższego poziomu w danym oknie; to ** nie ** przełącza ostrość między oknami. – JimEvans

+0

@JimEvans Dzięki za dostarczenie wnętrza 'WindowHandles'. Jak poradzisz sobie z jego problemem? – Saifur

+0

Zobacz moją odpowiedź na pytanie, jak poradzić sobie z problemem. – JimEvans

0

Mam kod, który może Ci się spodobać. Najszybszym rozwiązaniem jest użycie narzędzia Popup Finder, ale stworzyłem również własną metodę. Nigdy bym nie polegał na kolejności, w jakiej znajdują się uchwyty okienne, aby wybrać odpowiednie okno. Wyskakujące okienko Finder:

PopupWindowFinder finder = new PopupWindowFinder(driver); 
driver.SwitchTo().Window(newWin); 

Moja metoda niestandardowa. Zasadniczo podajesz element, który chcesz kliknąć, twój webdriver i opcjonalnie czas oczekiwania przed wyszukiwaniem po kliknięciu elementu.

Bierze wszystkie aktualne dźwignie i tworzy listę. Korzysta z tej listy, aby wyeliminować przypadkowo przełączane wcześniej okna. Następnie klika element, który uruchamia nowe okno.Po kliknięciu zawsze powinno być jakieś opóźnienie, ponieważ nic nie dzieje się natychmiast. Następnie tworzy nową listę i porównuje ją ze starym, dopóki nie znajdzie nowego okna lub pętla wygasa. Jeśli nie uda się znaleźć nowego okna, zwraca wartość null, więc jeśli masz wadliwy webelement, który nie zawsze działa, możesz wykonać zerową kontrolę, aby sprawdzić, czy przełącznik działa.

public static string ClickAndSwitchWindow(IWebElement elementToBeClicked, 
IWebDriver driver, int timer = 2000) 
     { 
      System.Collections.Generic.List<string> previousHandles = new 
System.Collections.Generic.List<string>(); 
      System.Collections.Generic.List<string> currentHandles = new 
System.Collections.Generic.List<string>(); 
     previousHandles.AddRange(driver.WindowHandles); 
     elementToBeClicked.Click(); 

     Thread.Sleep(timer); 
     for (int i = 0; i < 20; i++) 
     { 
      currentHandles.Clear(); 
      currentHandles.AddRange(driver.WindowHandles); 
      foreach (string s in previousHandles) 
      { 
       currentHandles.RemoveAll(p => p == s); 
      } 
      if (currentHandles.Count == 1) 
      { 
       driver.SwitchTo().Window(currentHandles[0]); 
       Thread.Sleep(100); 
       return currentHandles[0]; 
      } 
      else 
      { 
       Thread.Sleep(500); 
      } 
     } 
     return null; 
    } 
Powiązane problemy