popup的seleniumwebdrivers
所以我正在与C#winformselenium火狐webdrivers和我有下面的代码来获得popup窗口的句柄,当你点击“webtraffic_popup_start_button”,它应该得到popup的句柄,但popup的句柄是相同的作为目前的一个。
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);
任何帮助,将非常感谢你
这是popup的样子。
WebDriver绝对不会跟踪任何操作系统在前台检测哪个窗口,并且在新的浏览器窗口打开时不会自动切换。 这意味着获得新打开的popup窗口句柄的正确方法是一个多步骤的过程。 要做到这一点,你会:
- 将当前关注的窗口句柄保存到variables中,以便以后可以切换回。
- 获取当前打开的窗口句柄的列表。
- 执行会导致新窗口出现的操作。
- 等待窗口句柄的数量增加1。
- 获取窗口句柄的新列表。
- 在句柄列表中find新的句柄。
- 切换到新窗口。
在使用.NET语言绑定的代码中,这看起来像这样:
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);
或者,如果您使用的是.NET绑定,则WebDriver.Support程序集中有一个PopupWindowFinder
类,专门用于为您执行这些操作。 使用这个类是非常简单的。
// 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);
如果最后打开的窗口是您的目标,那么只需点击后执行以下操作
driver.SwitchTo().Window(driver.WindowHandles.ToList().Last());
编辑
//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();
我有一些你可能会喜欢的代码。 最快的解决方法是使用Popup Finder,但是我也做了我自己的方法。 我永远不会依赖窗口句柄在select适当的窗口。 popup窗口查找器:
PopupWindowFinder finder = new PopupWindowFinder(driver); driver.SwitchTo().Window(newWin);
我的自定义方法。 基本上,你通过它你想要点击的元素,你的web驱动程序,并select等待的时间,然后单击元素后search。
它需要你所有的当前句柄,并列出一个列表。 它使用该列表来消除以前存在的意外切换到的窗口。 然后它点击启动新窗口的元素。 在点击之后总会有某种延迟,因为没有任何事情立即发生。 然后创build一个新的列表,并将其与旧的列表进行比较,直到find新的窗口或循环过期。 如果它找不到新窗口,它将返回null,所以如果你有一个iffy webelement不总是工作,你可以做一个空的检查,看看交换机是否工作。
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; }