| 1427 | } |
| 1428 | |
| 1429 | std::string IECommandExecutor::OpenNewBrowserTab(const std::wstring& url) { |
| 1430 | LOG(TRACE) << "Entering IECommandExecutor::OpenNewBrowserTab"; |
| 1431 | BrowserHandle browser_wrapper; |
| 1432 | this->GetCurrentBrowser(&browser_wrapper); |
| 1433 | HWND top_level_handle = browser_wrapper->GetTopLevelWindowHandle(); |
| 1434 | |
| 1435 | if (this->is_edge_chromium_) { |
| 1436 | // This is a hack to account for the case where the currently focused |
| 1437 | // WebDriver window is a tab without the visual focus. When an IE Mode |
| 1438 | // tab is sent to the background, it is reparented to a different top- |
| 1439 | // level window than the Edge window. To detect a new tab being opened, |
| 1440 | // we must find a top-level Edge window containing and active IE Mode |
| 1441 | // tab, and use that as our parent window. This is a rare case that |
| 1442 | // will only happen if the user does not switch WebDriver command focus |
| 1443 | // to the new window immediately after opening. The Selenium language |
| 1444 | // bindings do this automatically, but non-Selenium client bindings may |
| 1445 | // not do so. |
| 1446 | // ASSUMPTION: The first top-level Edge window we find containing an IE |
| 1447 | // Mode tab is the top-level window we want. |
| 1448 | std::string window_class = |
| 1449 | WindowUtilities::GetWindowClass(top_level_handle); |
| 1450 | if (window_class != "Chrome_WidgetWin_1") { |
| 1451 | std::vector<HWND> edge_handles; |
| 1452 | ::EnumWindows(&BrowserFactory::FindEdgeBrowserHandles, |
| 1453 | reinterpret_cast<LPARAM>(&edge_handles)); |
| 1454 | for (auto& edge_handle : edge_handles) { |
| 1455 | std::vector<HWND> ie_mode_handles; |
| 1456 | ::EnumChildWindows(edge_handle, |
| 1457 | &BrowserFactory::FindIEBrowserHandles, |
| 1458 | reinterpret_cast<LPARAM>(&ie_mode_handles)); |
| 1459 | if (ie_mode_handles.size() > 0) { |
| 1460 | top_level_handle = edge_handle; |
| 1461 | break; |
| 1462 | } |
| 1463 | } |
| 1464 | } |
| 1465 | } |
| 1466 | |
| 1467 | std::vector<HWND> original_handles; |
| 1468 | ::EnumChildWindows(top_level_handle, |
| 1469 | &BrowserFactory::FindIEBrowserHandles, |
| 1470 | reinterpret_cast<LPARAM>(&original_handles)); |
| 1471 | std::sort(original_handles.begin(), original_handles.end()); |
| 1472 | |
| 1473 | // IWebBrowser2::Navigate2 will open the specified URL in a new tab, |
| 1474 | // if requested. The Sleep() call after the navigate is necessary, |
| 1475 | // since the IECommandExecutor class doesn't have access to the events |
| 1476 | // to indicate the navigation is completed. |
| 1477 | CComVariant url_variant = url.c_str(); |
| 1478 | CComVariant flags = navOpenInNewTab; |
| 1479 | browser_wrapper->browser()->Navigate2(&url_variant, |
| 1480 | &flags, |
| 1481 | NULL, |
| 1482 | NULL, |
| 1483 | NULL); |
| 1484 | ::Sleep(500); |
| 1485 | |
| 1486 | HWND new_tab_window = NULL; |
no test coverage detected