Popup's in selenium webdrivers

前端 未结 3 2107
猫巷女王i
猫巷女王i 2020-11-27 05:01

So I\'m working with selenium firefox webdrivers in c# winform and I have this code below to get the handle of the popup that shows when you click on the \"webtraffic_popup_

相关标签:
3条回答
  • 2020-11-27 05:18

    I've got some code you might like. The quickest solution is to use Popup Finder, but I've made my own method as well. I would never rely on the order the Window Handles are in to select the appropriate window. Popup Window Finder:

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

    My Custom method. Basically you pass it the element you want to click, your webdriver, and optionally the time to wait before searching after you click the element.

    It takes all of your current handles and makes a list. It uses that list to eliminate the previously existing windows from accidentally getting switched to. Then it clicks the element that launches the new window. There should always be some sort of a delay after the click, as nothing happens instantly. And then it makes a new list and compares that against the old one until it finds a new window or the loop expires. If it fails to find a new window it returns null, so if you have an iffy webelement that doesn't always work, you can do a null check to see if the switch worked.

    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;
        }
    
    0 讨论(0)
  • 2020-11-27 05:30

    WebDriver does absolutely no tracking whatsoever to detect which window is actually in the foreground in the OS, and does no automatic switching when new browser windows are opened. That means the proper way to get the handle of a newly-opened popup window is a multi-step process. To do so, you would:

    1. Save the currently-focused window handle into a variable so that you can switch back to it later.
    2. Get the list of currently opened window handles.
    3. Perform the action that would cause the new window to appear.
    4. Wait for the number of window handles to increase by 1.
    5. Get the new list of window handles.
    6. Find the new handle in the list of handles.
    7. Switch to that new window.

    In code using the .NET language bindings, that would look something like this:

    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);
    

    Alternatively, if you're using the .NET bindings, there's a PopupWindowFinder class in the WebDriver.Support assembly that is specifically designed to do these operations for you. Using that class is much simpler.

    // 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);
    
    0 讨论(0)
  • 2020-11-27 05:30

    If the lastly opened window is your target then simply do the following after the click

    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();
    
    0 讨论(0)
提交回复
热议问题