New window handles disappearing in IE, can't s

2019-02-15 20:36发布

问题:

I am using the latest version of Selenium (2.37.0) with C# in Internet Explorer 10 (using the latest 32-bit InternetExplorerDriver, 2.37.0) to log in to a webpage, click on a button that opens a new window, and then changes focus to the new window.

Originally I was using this code in Firefox, and it would work every time:

// Get handle for original window
string parentHandle = driver.CurrentWindowHandle;

// Click on button for new window
driver.FindElement(By.Id("buttonForNewWindow")).Click();

// Get list of all window handles
ReadOnlyCollection<string> allWindowHandles = driver.WindowHandles;

// Loop over all handles and switch to new child window
foreach (string handle in allWindowHandles)
{
    if (handle != parentHandle)
    {
        driver.SwitchTo().Window(handle);
    }
}

But this doesn't work in Internet Explorer.

I have pinpointed the problem. Before I open the new window, I use driver.WindowHandles.Count to get the number of window handles, and (as expected) it tells me that there is only one window handle. Then, when I click the button for the new window, it tells me (again, as expected) that there are two window handles. But before the code gets to the line for driver.SwitchTo().Window(handle);, the number of window handles has dropped back down to one, even though both windows are still visible.

So somehow one of the window handles is getting lost. I have confirmed (using a bunch of Console.WriteLine statements) that the window handle that is dropped is the new one. I also used the Stopwatch class to time how long it takes for the new window handle to be dropped:

Stopwatch sw = new Stopwatch();

// Wait until the number of windows has changed from 1 to 2
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
wait.Until((_driver) => { return _driver.WindowHandles.Count != windowsBefore; });

// Start stopwatch
sw.Start();

int numberOfWindows = driver.WindowHandles.Count;

while (numberOfWindows == 2)
{
    numberOfWindows = driver.WindowHandles.Count;
}

sw.Stop();

Console.Write("\nTime elapsed: " + sw.ElapsedMilliseconds + " ms");

After running this a few times, I found that the number of window handles typically drops back to one in less than 50 milliseconds. However, one time the window handle lasted much longer; here are the original numbers:

Time elapsed: 47 ms
Time elapsed: 31 ms
Time elapsed: 47 ms
Time elapsed: 2861 ms
Time elapsed: 30 ms

I have also confirmed that this problem does not occur in Firefox. When I run the same code in Firefox, I find that the number of window handles changes from 1 to 2, and stays that way, as it should.

It seems that others are having this problem as well. This person finds that when they open a new window and wait 1000 milliseconds, getWindowHandles() returns a value of 1 instead of 2. And this person on the Selenium Google Group seems to be having the same issue.

My question: Given that the handle for a newly-opened window remains open for (typically) less than 50 milliseconds, what is the most efficient possible way to switch to a new window in Internet Explorer 10 with Selenium? Or is there something I should be doing differently to prevent new window handles from getting lost?

回答1:

Just wanted to give an update, in case anyone else has this same problem and finds this page. I haven't found a solution to my problem, but I came up with a workaround.

Originally, I was clicking on a link that opened a new window, and I was having trouble navigating Selenium to the new window. What I did instead was dig through the page's source code, find the button that I was clicking on, and figure out where that button points to. It would have been easiest if it was a simple hyperlink (www.whatever.com/....), but instead it was a Javascript function. That Javascript function builds up the hyperlink using some fixed characters and some variables; for example:

link(username, date) = "http://www.google.com/user=" + username + "?date=" + date;

So, going along with this example, I just figured out what variables were being fed in (username, date, etc.), built the URL myself, and navigated to it directly. Thus I didn't even have to open up and navigate to a new window at all.