15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/bind.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/file_util.h" 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/format_macros.h" 89ab5563a3196760eb381d102cbb2bc0f7abc6a50Ben Murdoch#include "base/message_loop/message_loop.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/path_service.h" 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/strings/string_number_conversions.h" 11868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 12868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/utf_string_conversions.h" 137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_commands.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_tabstrip.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/browser_window.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/chrome_pages.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/omnibox/location_bar.h" 202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/omnibox/omnibox_edit_controller.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/omnibox/omnibox_edit_model.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/browser/ui/omnibox/omnibox_view.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/browser/ui/view_ids.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/chrome_paths.h" 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/common/url_constants.h" 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h" 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "chrome/test/base/interactive_test_utils.h" 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h" 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/interstitial_page.h" 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/interstitial_page_delegate.h" 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/notification_service.h" 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_view_host.h" 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/render_widget_host_view.h" 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents.h" 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/web_contents_view.h" 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/test/browser_test_utils.h" 38eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "net/test/embedded_test_server/embedded_test_server.h" 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <windows.h> 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <Psapi.h> 43868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/string_util.h" 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::InterstitialPage; 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::NavigationController; 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::RenderViewHost; 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using content::WebContents; 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(suzhe): http://crbug.com/60973 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_FocusTraversal DISABLED_FocusTraversal 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_FocusTraversalOnInterstitial DISABLED_FocusTraversalOnInterstitial 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#elif defined(OS_WIN) || defined(OS_CHROMEOS) 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// http://crbug.com/109770 and http://crbug.com/62544 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_FocusTraversal FocusTraversal 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_FocusTraversalOnInterstitial DISABLED_FocusTraversalOnInterstitial 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_FocusTraversal FocusTraversal 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_FocusTraversalOnInterstitial FocusTraversalOnInterstitial 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_LINUX) || defined(OS_MACOSX) 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(jcampan): http://crbug.com/23683 for linux. 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TODO(suzhe): http://crbug.com/49737 for mac. 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_TabsRememberFocusFindInPage DISABLED_TabsRememberFocusFindInPage 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Flaky, http://crbug.com/62537. 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_TabsRememberFocusFindInPage DISABLED_TabsRememberFocusFindInPage 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace { 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// The delay waited in some cases where we don't have a notifications for an 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// action we take. 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kActionDelayMs = 500; 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Maxiumum time to wait until the focus is moved to expected view. 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const int kFocusChangeTimeoutMs = 500; 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 82eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char kSimplePage[] = "/focus/page_with_focus.html"; 83eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char kStealFocusPage[] = "/focus/page_steals_focus.html"; 84eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdochconst char kTypicalPage[] = "/focus/typical_page.html"; 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const char kTypicalPageName[] = "typical_page.html"; 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Test to make sure Chrome is in the foreground as we start testing. This is 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// required for tests that synthesize input to the Chrome window. 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool ChromeInForeground() { 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HWND window = ::GetForegroundWindow(); 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring caption; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::wstring filename; 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int len = ::GetWindowTextLength(window) + 1; 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (len > 1) 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ::GetWindowText(window, WriteInto(&caption, len), len); 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool chrome_window_in_foreground = 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EndsWith(caption, L" - Google Chrome", true) || 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EndsWith(caption, L" - Chromium", true); 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!chrome_window_in_foreground) { 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DWORD process_id; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int thread_id = ::GetWindowThreadProcessId(window, &process_id); 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::ProcessHandle process; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base::OpenProcessHandleWithAccess(process_id, 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) PROCESS_QUERY_LIMITED_INFORMATION, 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &process)) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (!GetProcessImageFileName(process, WriteInto(&filename, MAX_PATH), 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) MAX_PATH)) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int error = GetLastError(); 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) filename = std::wstring(L"Unable to read filename for process id '" + 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::IntToString16(process_id) + 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) L"' (error ") + 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::IntToString16(error) + L")"; 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::CloseProcessHandle(process); 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(chrome_window_in_foreground) 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Chrome must be in the foreground when running interactive tests\n" 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Process in foreground: " << filename.c_str() << "\n" 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Window: " << window << "\n" 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) << "Caption: " << caption.c_str(); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return chrome_window_in_foreground; 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Windows only at the moment. 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Wait the focus change in message loop. 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CheckFocus(Browser* browser, ViewID id, const base::Time& timeout) { 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ui_test_utils::IsViewFocused(browser, id) || 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Time::Now() > timeout) { 135b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostTask(FROM_HERE, 136b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::QuitClosure()); 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 138b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CheckFocus, browser, id, timeout), 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(10)); 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BrowserFocusTest : public InProcessBrowserTest { 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool IsViewFocused(ViewID vid) { 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ui_test_utils::IsViewFocused(browser(), vid); 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void ClickOnView(ViewID vid) { 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_test_utils::ClickOnView(browser(), vid); 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool WaitForFocusChange(ViewID vid) { 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::Time timeout = base::Time::Now() + 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kFocusChangeTimeoutMs); 158b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::Bind(&CheckFocus, browser(), vid, timeout), 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(100)); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RunMessageLoop(); 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return IsViewFocused(vid); 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestInterstitialPage : public content::InterstitialPageDelegate { 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TestInterstitialPage(WebContents* tab, bool new_navigation, const GURL& url) { 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::FilePath file_path; 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool r = PathService::Get(chrome::DIR_TEST_DATA, &file_path); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(r); 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_path = file_path.AppendASCII("focus"); 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) file_path = file_path.AppendASCII(kTypicalPageName); 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) r = file_util::ReadFileToString(file_path, &html_contents_); 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(r); 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interstitial_page_ = InterstitialPage::Create( 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) tab, new_navigation, url , this); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interstitial_page_->Show(); 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual std::string GetHTMLContents() OVERRIDE { 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return html_contents_; 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RenderViewHost* render_view_host() { 1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return interstitial_page_->GetRenderViewHostForTesting(); 1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) void DontProceed() { 1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interstitial_page_->DontProceed(); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool HasFocus() { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return render_view_host()->GetView()->HasFocus(); 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string html_contents_; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) InterstitialPage* interstitial_page_; // Owns us. 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Flaky on mac. http://crbug.com/67301. 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_ClickingMovesFocus DISABLED_ClickingMovesFocus 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#define MAYBE_ClickingMovesFocus ClickingMovesFocus 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_ClickingMovesFocus) { 2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_POSIX) 2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It seems we have to wait a little bit for the widgets to spin up before 2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // we can start clicking on them. 214b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FROM_HERE, 216b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::QuitClosure(), 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromMilliseconds(kActionDelayMs)); 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RunMessageLoop(); 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // defined(OS_POSIX) 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); 2225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClickOnView(VIEW_ID_TAB_CONTAINER); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER)); 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ClickOnView(VIEW_ID_OMNIBOX); 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Flaky, http://crbug.com/69034. 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_BrowsersRememberFocus) { 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 233eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First we navigate to our test page. 236eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url = embedded_test_server()->GetURL(kSimplePage); 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_test_utils::NavigateToURL(browser(), url); 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::NativeWindow window = browser()->window()->GetNativeWindow(); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The focus should be on the Tab contents. 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER)); 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now hide the window, show it again, the focus should not have changed. 2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_test_utils::HideNativeWindow(window); 2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(window)); 2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER)); 2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::FocusLocationBar(browser()); 2492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hide the window, show it again, the focus should not have changed. 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_test_utils::HideNativeWindow(window); 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::ShowAndFocusNativeWindow(window)); 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tabs remember focus. 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Disabled, http://crbug.com/62542. 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_TabsRememberFocus) { 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 260eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First we navigate to our test page. 263eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url = embedded_test_server()->GetURL(kSimplePage); 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_test_utils::NavigateToURL(browser(), url); 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create several tabs. 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 4; ++i) { 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::AddSelectedTabWithURL(browser(), url, 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PAGE_TRANSITION_TYPED); 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Alternate focus for the tab. 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const bool kFocusPage[3][5] = { 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { true, true, true, true, false }, 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { false, false, false, false, false }, 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { false, true, false, true, false } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 1; i < 3; i++) { 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < 5; j++) { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Activate the tab. 2822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->ActivateTabAt(j, true); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Activate the location bar or the page. 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (kFocusPage[i][j]) { 2862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->GetWebContentsAt(j)->GetView()->Focus(); 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::FocusLocationBar(browser()); 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now come back to the tab and check the right view is focused. 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < 5; j++) { 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Activate the tab. 2952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->ActivateTabAt(j, true); 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ViewID vid = kFocusPage[i][j] ? VIEW_ID_TAB_CONTAINER : VIEW_ID_OMNIBOX; 2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(vid)); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->ActivateTabAt(0, true); 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Try the above, but with ctrl+tab. Since tab normally changes focus, 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // this has regressed in the past. Loop through several times to be sure. 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 0; j < 15; j++) { 3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ViewID vid = kFocusPage[i][j % 5] ? VIEW_ID_TAB_CONTAINER : 3062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VIEW_ID_OMNIBOX; 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(vid)); 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::SendKeyPressSync( 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser(), ui::VKEY_TAB, true, false, false, false)); 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // As above, but with ctrl+shift+tab. 3142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->ActivateTabAt(4, true); 3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int j = 14; j >= 0; --j) { 3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ViewID vid = kFocusPage[i][j % 5] ? VIEW_ID_TAB_CONTAINER : 3172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VIEW_ID_OMNIBOX; 3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(vid)); 3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::SendKeyPressSync( 3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser(), ui::VKEY_TAB, true, true, false, false)); 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tabs remember focus with find-in-page box. 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_TabsRememberFocusFindInPage) { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 329eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 3305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First we navigate to our test page. 332eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url = embedded_test_server()->GetURL(kSimplePage); 3335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_test_utils::NavigateToURL(browser(), url); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::Find(browser()); 3362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ui_test_utils::FindInPage( 3372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->GetActiveWebContents(), 3382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASCIIToUTF16("a"), true, false, NULL, NULL); 3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD)); 3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Focus the location bar. 3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::FocusLocationBar(browser()); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a 2nd tab. 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::AddSelectedTabWithURL(browser(), url, content::PAGE_TRANSITION_TYPED); 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Focus should be on the recently opened tab page. 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER)); 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Select 1st tab, focus should still be on the location-bar. 3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (bug http://crbug.com/23296) 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->ActivateTabAt(0, true); 3532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); 3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now open the find box again, switch to another tab and come back, the focus 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // should return to the find box. 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::Find(browser()); 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD)); 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->ActivateTabAt(1, true); 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER)); 3612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->ActivateTabAt(0, true); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD)); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Background window does not steal focus. 3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Flaky, http://crbug.com/62538. 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowserFocusTest, 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISABLED_BackgroundBrowserDontStealFocus) { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 370eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open a new browser window. 3732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Browser* browser2 = 3742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new Browser(Browser::CreateParams(browser()->profile(), 3752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->host_desktop_type())); 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(browser2); 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::AddBlankTabAt(browser2, -1, true); 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser2->window()->Show(); 3795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* focused_browser = NULL; 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Browser* unfocused_browser = NULL; 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(USE_X11) 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On X11, calling Activate() is not guaranteed to move focus, so we have 3845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to figure out which browser does have focus. 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (browser2->window()->IsActive()) { 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) focused_browser = browser2; 3875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unfocused_browser = browser(); 3885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else if (browser()->window()->IsActive()) { 3895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) focused_browser = browser(); 3905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unfocused_browser = browser2; 3915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FAIL() << "Could not determine which browser has focus"; 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_WIN) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) focused_browser = browser(); 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unfocused_browser = browser2; 3975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#elif defined(OS_MACOSX) 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On Mac, the newly created window always gets the focus. 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) focused_browser = browser2; 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) unfocused_browser = browser(); 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 403eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL steal_focus_url = embedded_test_server()->GetURL(kStealFocusPage); 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_test_utils::NavigateToURL(unfocused_browser, steal_focus_url); 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Activate the first browser. 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) focused_browser->window()->Activate(); 4085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(content::ExecuteScript( 4102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) unfocused_browser->tab_strip_model()->GetActiveWebContents(), 4112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "stealFocus();")); 4125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the first browser is still active. 4145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(focused_browser->window()->IsActive()); 4155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Page cannot steal focus when focus is on location bar. 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowserFocusTest, LocationBarLockFocus) { 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 420eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open the page that steals focus. 423eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url = embedded_test_server()->GetURL(kStealFocusPage); 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_test_utils::NavigateToURL(browser(), url); 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::FocusLocationBar(browser()); 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(content::ExecuteScript( 4292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->GetActiveWebContents(), 4302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "stealFocus();")); 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Make sure the location bar is still focused. 4332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Focus traversal on a regular page. 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Note that this test relies on a notification from the renderer that the 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// focus has changed in the page. The notification in the renderer may change 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// at which point this test would fail (see comment in 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// RenderWidget::didFocus()). 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_FocusTraversal) { 4425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 443eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First we navigate to our test page. 446eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url = embedded_test_server()->GetURL(kTypicalPage); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_test_utils::NavigateToURL(browser(), url); 4485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::FocusLocationBar(browser()); 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* kTextElementID = "textEdit"; 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* kExpElementIDs[] = { 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "", // Initially no element in the page should be focused 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (the location bar is focused). 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kTextElementID, "searchButton", "luckyButton", "googleLink", "gmailLink", 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "gmapLink" 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test forward focus traversal. 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 3; ++i) { 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCOPED_TRACE(base::StringPrintf("outer loop: %d", i)); 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Location bar should be focused. 4632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Move the caret to the end, otherwise the next Tab key may not move focus. 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::SendKeyPressSync( 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser(), ui::VKEY_END, false, false, false, false)); 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now let's press tab to move the focus. 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t j = 0; j < arraysize(kExpElementIDs); ++j) { 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCOPED_TRACE(base::StringPrintf("inner loop %" PRIuS, j)); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Let's make sure the focus is on the expected element in the page. 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string actual; 4742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(content::ExecuteScriptAndExtractString( 4752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->GetActiveWebContents(), 4762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "window.domAutomationController.send(getFocusedElement());", 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &actual)); 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_STREQ(kExpElementIDs[j], actual.c_str()); 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (j < arraysize(kExpElementIDs) - 1) { 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the next element is the kTextElementID, we expect to be 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notified we have switched to an editable node. 4835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_editable_node = 4845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) (strcmp(kTextElementID, kExpElementIDs[j + 1]) == 0); 4855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<bool> details(&is_editable_node); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::SendKeyPressAndWaitWithDetails( 4885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser(), ui::VKEY_TAB, false, false, false, false, 4895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationSource(content::Source<RenderViewHost>( 4912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->GetActiveWebContents()-> 4922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRenderViewHost())), 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) details)); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On the last tab key press, the focus returns to the browser. 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser(), ui::VKEY_TAB, false, false, false, false, 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_FOCUS_RETURNED_TO_BROWSER, 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationSource(content::Source<Browser>(browser())))); 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // At this point the renderer has sent us a message asking to advance the 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // focus (as the end of the focus loop was reached in the renderer). 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to run the message loop to process it. 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RunAllPendingInMessageLoop(); 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now let's try reverse focus traversal. 5105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 3; ++i) { 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCOPED_TRACE(base::StringPrintf("outer loop: %d", i)); 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Location bar should be focused. 5132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); 5145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Move the caret to the end, otherwise the next Tab key may not move focus. 5165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::SendKeyPressSync( 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser(), ui::VKEY_END, false, false, false, false)); 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now let's press shift-tab to move the focus in reverse. 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t j = 0; j < arraysize(kExpElementIDs); ++j) { 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SCOPED_TRACE(base::StringPrintf("inner loop: %" PRIuS, j)); 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* next_element = 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kExpElementIDs[arraysize(kExpElementIDs) - 1 - j]; 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (j < arraysize(kExpElementIDs) - 1) { 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // If the next element is the kTextElementID, we expect to be 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // notified we have switched to an editable node. 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_editable_node = (strcmp(kTextElementID, next_element) == 0); 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Details<bool> details(&is_editable_node); 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::SendKeyPressAndWaitWithDetails( 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser(), ui::VKEY_TAB, false, true, false, false, 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE, 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationSource(content::Source<RenderViewHost>( 5352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->GetActiveWebContents()-> 5362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRenderViewHost())), 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) details)); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On the last tab key press, the focus returns to the browser. 5405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( 5415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser(), ui::VKEY_TAB, false, true, false, false, 5425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NOTIFICATION_FOCUS_RETURNED_TO_BROWSER, 5435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationSource(content::Source<Browser>(browser())))); 5445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Let's make sure the focus is on the expected element in the page. 5475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string actual; 5482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(content::ExecuteScriptAndExtractString( 5492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->GetActiveWebContents(), 5502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "window.domAutomationController.send(getFocusedElement());", 5515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &actual)); 5525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_STREQ(next_element, actual.c_str()); 5535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // At this point the renderer has sent us a message asking to advance the 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // focus (as the end of the focus loop was reached in the renderer). 5575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to run the message loop to process it. 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RunAllPendingInMessageLoop(); 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Focus traversal while an interstitial is showing. 5635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowserFocusTest, MAYBE_FocusTraversalOnInterstitial) { 5645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 565eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 5665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First we navigate to our test page. 568eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url = embedded_test_server()->GetURL(kSimplePage); 5695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_test_utils::NavigateToURL(browser(), url); 5705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Focus should be on the page. 5725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER)); 5735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Let's show an interstitial. 5752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestInterstitialPage* interstitial_page = new TestInterstitialPage( 5762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->GetActiveWebContents(), 5772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true, GURL("http://interstitial.com")); 5785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Give some time for the interstitial to show. 579b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 580b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) FROM_HERE, 581b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::QuitClosure(), 582b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::TimeDelta::FromSeconds(1)); 5835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RunMessageLoop(); 5845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::FocusLocationBar(browser()); 5865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const char* kExpElementIDs[] = { 5885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "", // Initially no element in the page should be focused 5895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (the location bar is focused). 5905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "textEdit", "searchButton", "luckyButton", "googleLink", "gmailLink", 5915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "gmapLink" 5925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) }; 5935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Test forward focus traversal. 5955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 2; ++i) { 5965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Location bar should be focused. 5972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); 5985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Move the caret to the end, otherwise the next Tab key may not move focus. 6005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::SendKeyPressSync( 6015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser(), ui::VKEY_END, false, false, false, false)); 6025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now let's press tab to move the focus. 6045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t j = 0; j < 7; ++j) { 6055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Let's make sure the focus is on the expected element in the page. 6065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string actual; 6072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(content::ExecuteScriptAndExtractString( 6082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) interstitial_page->render_view_host(), 6092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "window.domAutomationController.send(getFocusedElement());", 6105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &actual)); 6115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_STREQ(kExpElementIDs[j], actual.c_str()); 6125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int notification_type; 6145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationSource notification_source = 6155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::AllSources(); 6165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (j < arraysize(kExpElementIDs) - 1) { 6175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_type = content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE; 6185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_source = content::Source<RenderViewHost>( 6195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interstitial_page->render_view_host()); 6205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On the last tab key press, the focus returns to the browser. 6225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_type = chrome::NOTIFICATION_FOCUS_RETURNED_TO_BROWSER; 6235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_source = content::Source<Browser>(browser()); 6245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( 6275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser(), ui::VKEY_TAB, false, false, false, false, 6285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_type, notification_source)); 6295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // At this point the renderer has sent us a message asking to advance the 6325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // focus (as the end of the focus loop was reached in the renderer). 6335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to run the message loop to process it. 6345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RunAllPendingInMessageLoop(); 6355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now let's try reverse focus traversal. 6385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (int i = 0; i < 2; ++i) { 6395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Location bar should be focused. 6402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); 6415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Move the caret to the end, otherwise the next Tab key may not move focus. 6435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::SendKeyPressSync( 6445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser(), ui::VKEY_END, false, false, false, false)); 6455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now let's press shift-tab to move the focus in reverse. 6475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) for (size_t j = 0; j < 7; ++j) { 6485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int notification_type; 6495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationSource notification_source = 6505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::AllSources(); 6515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (j < arraysize(kExpElementIDs) - 1) { 6525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_type = content::NOTIFICATION_FOCUS_CHANGED_IN_PAGE; 6535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_source = content::Source<RenderViewHost>( 6545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interstitial_page->render_view_host()); 6555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 6565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // On the last tab key press, the focus returns to the browser. 6575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_type = chrome::NOTIFICATION_FOCUS_RETURNED_TO_BROWSER; 6585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_source = content::Source<Browser>(browser()); 6595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::SendKeyPressAndWait( 6625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser(), ui::VKEY_TAB, false, true, false, false, 6635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) notification_type, notification_source)); 6645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Let's make sure the focus is on the expected element in the page. 6665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) std::string actual; 6672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(content::ExecuteScriptAndExtractString( 6682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) interstitial_page->render_view_host(), 6692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "window.domAutomationController.send(getFocusedElement());", 6705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) &actual)); 6715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_STREQ(kExpElementIDs[6 - j], actual.c_str()); 6725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // At this point the renderer has sent us a message asking to advance the 6755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // focus (as the end of the focus loop was reached in the renderer). 6765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We need to run the message loop to process it. 6775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RunAllPendingInMessageLoop(); 6785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 6795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 6805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Focus stays on page with interstitials. 6825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// http://crbug.com/81451 6835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_InterstitialFocus) { 6845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 685eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 6865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // First we navigate to our test page. 688eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url = embedded_test_server()->GetURL(kSimplePage); 6895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_test_utils::NavigateToURL(browser(), url); 6905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Page should have focus. 6925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER)); 6932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(browser()->tab_strip_model()->GetActiveWebContents()-> 6942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetRenderViewHost()->GetView()->HasFocus()); 6955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 6965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Let's show an interstitial. 6972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) TestInterstitialPage* interstitial_page = new TestInterstitialPage( 6982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->GetActiveWebContents(), 6992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) true, GURL("http://interstitial.com")); 7005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Give some time for the interstitial to show. 701b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::current()->PostDelayedTask( 702b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) FROM_HERE, 703b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::MessageLoop::QuitClosure(), 704b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles) base::TimeDelta::FromSeconds(1)); 7055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RunMessageLoop(); 7065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The interstitial should have focus now. 7085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER)); 7095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(interstitial_page->HasFocus()); 7105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Hide the interstitial. 7125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) interstitial_page->DontProceed(); 7135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Focus should be back on the original page. 7155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER)); 7165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Make sure Find box can request focus, even when it is already open. 7195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Disabled due to flakiness. http://crbug.com/67301. 7205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_FindFocusTest) { 7215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 722eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 7235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open some page (any page that doesn't steal focus). 725eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch GURL url = embedded_test_server()->GetURL(kTypicalPage); 7265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui_test_utils::NavigateToURL(browser(), url); 7275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(ChromeInForeground()); 7295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 7315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Press Cmd+F, which will make the Find box open and request focus. 7325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::SendKeyPressSync( 7335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser(), ui::VKEY_F, false, false, false, true)); 7345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 7355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Press Ctrl+F, which will make the Find box open and request focus. 7365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::SendKeyPressSync( 7375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser(), ui::VKEY_F, true, false, false, false)); 7385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(WaitForFocusChange(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD)); 7415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::FocusLocationBar(browser()); 7432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); 7445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now press Ctrl+F again and focus should move to the Find box. 7465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 7475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::SendKeyPressSync( 7485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser(), ui::VKEY_F, false, false, false, true)); 7495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 7505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::SendKeyPressSync( 7515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser(), ui::VKEY_F, true, false, false, false)); 7525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD)); 7545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Set focus to the page. 7565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClickOnView(VIEW_ID_TAB_CONTAINER); 7575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER)); 7585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Now press Ctrl+F again and focus should move to the Find box. 7605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_MACOSX) 7615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::SendKeyPressSync( 7625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser(), ui::VKEY_F, false, false, false, true)); 7635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#else 7645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::SendKeyPressSync( 7655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) browser(), ui::VKEY_F, true, false, false, false)); 7665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 7675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(WaitForFocusChange(VIEW_ID_FIND_IN_PAGE_TEXT_FIELD)); 7695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 7705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Makes sure the focus is in the right location when opening the different 7725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// types of tabs. 7735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Flaky, http://crbug.com/62539. 7745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_TabInitialFocus) { 7755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 7765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open the history tab, focus should be on the tab contents. 7785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::ShowHistory(browser()); 7795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NO_FATAL_FAILURE(content::WaitForLoadStop( 7802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->GetActiveWebContents())); 7815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER)); 7825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open the new tab, focus should be on the location bar. 7845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NewTab(browser()); 7855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NO_FATAL_FAILURE(content::WaitForLoadStop( 7862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->GetActiveWebContents())); 7872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); 7885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open the download tab, focus should be on the tab contents. 7905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::ShowDownloads(browser()); 7915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NO_FATAL_FAILURE(content::WaitForLoadStop( 7922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->GetActiveWebContents())); 7935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) EXPECT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER)); 7945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 7955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open about:blank, focus should be on the location bar. 79690dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) chrome::AddSelectedTabWithURL(browser(), GURL(content::kAboutBlankURL), 7975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::PAGE_TRANSITION_LINK); 7985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_NO_FATAL_FAILURE(content::WaitForLoadStop( 7992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->tab_strip_model()->GetActiveWebContents())); 8002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); 8015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that focus goes where expected when using reload. 8045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusOnReload) { 8055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 806eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 8075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open the new tab, reload. 8095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WindowedNotificationObserver observer( 8115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NOTIFICATION_LOAD_STOP, 8125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NotificationService::AllSources()); 8135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::NewTab(browser()); 8145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer.Wait(); 8155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::RunAllPendingInMessageLoop(); 8175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WindowedNotificationObserver observer( 8205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NOTIFICATION_LOAD_STOP, 8215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<NavigationController>( 8222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &browser()->tab_strip_model()->GetActiveWebContents()-> 8232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetController())); 8245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::Reload(browser(), CURRENT_TAB); 8255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer.Wait(); 8265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Focus should stay on the location bar. 8282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); 8295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open a regular page, focus the location bar, reload. 831eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ui_test_utils::NavigateToURL(browser(), 832eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch embedded_test_server()->GetURL(kSimplePage)); 8335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::FocusLocationBar(browser()); 8342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); 8355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WindowedNotificationObserver observer( 8375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NOTIFICATION_LOAD_STOP, 8385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<NavigationController>( 8392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &browser()->tab_strip_model()->GetActiveWebContents()-> 8402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetController())); 8415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::Reload(browser(), CURRENT_TAB); 8425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer.Wait(); 8435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Focus should now be on the tab contents. 8465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::ShowDownloads(browser()); 8475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER)); 8485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that focus goes where expected when using reload on a crashed tab. 8515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowserFocusTest, DISABLED_FocusOnReloadCrashedTab) { 8525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 853eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ASSERT_TRUE(embedded_test_server()->InitializeAndWaitUntilReady()); 8545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Open a regular page, crash, reload. 856eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch ui_test_utils::NavigateToURL(browser(), 857eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch embedded_test_server()->GetURL(kSimplePage)); 8582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::CrashTab(browser()->tab_strip_model()->GetActiveWebContents()); 8595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) { 8605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::WindowedNotificationObserver observer( 8615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::NOTIFICATION_LOAD_STOP, 8625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) content::Source<NavigationController>( 8632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &browser()->tab_strip_model()->GetActiveWebContents()-> 8642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GetController())); 8655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::Reload(browser(), CURRENT_TAB); 8665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) observer.Wait(); 8675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 8685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Focus should now be on the tab contents. 8705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) chrome::ShowDownloads(browser()); 8715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ASSERT_TRUE(IsViewFocused(VIEW_ID_TAB_CONTAINER)); 8725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 8735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 8742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Tests that when a new tab is opened from the omnibox, the focus is moved from 8752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// the omnibox for the current tab. 8762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowserFocusTest, 8772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) NavigateFromOmniboxIntoNewTab) { 8782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url("http://www.google.com/"); 8792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) GURL url2("http://maps.google.com/"); 8802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Navigate to url. 8822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::NavigateParams p(browser(), url, content::PAGE_TRANSITION_LINK); 8832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) p.window_action = chrome::NavigateParams::SHOW_WINDOW; 8842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) p.disposition = CURRENT_TAB; 8852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::Navigate(&p); 8862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Focus the omnibox. 8882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::FocusLocationBar(browser()); 8892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) OmniboxEditController* controller = 8912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) browser()->window()->GetLocationBar()->GetLocationEntry()->model()-> 8922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) controller(); 8932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Simulate an alt-enter. 8952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) controller->OnAutocompleteAccept(url2, NEW_FOREGROUND_TAB, 8962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) content::PAGE_TRANSITION_TYPED, GURL()); 8972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 8982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Make sure the second tab is selected. 8992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(1, browser()->tab_strip_model()->active_index()); 9002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // The tab contents should have the focus in the second tab. 9022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_TAB_CONTAINER)); 9032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 9042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Go back to the first tab. The focus should not be in the omnibox. 9052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) chrome::SelectPreviousTab(browser()); 9062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_EQ(0, browser()->tab_strip_model()->active_index()); 9072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_FALSE(ui_test_utils::IsViewFocused(browser(), VIEW_ID_OMNIBOX)); 9082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 9092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 910c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)IN_PROC_BROWSER_TEST_F(BrowserFocusTest, FocusOnNavigate) { 911c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Needed on Mac. 912c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ASSERT_TRUE(ui_test_utils::BringBrowserWindowToFront(browser())); 913c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Load the NTP. 914c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui_test_utils::NavigateToURL(browser(), GURL(chrome::kChromeUINewTabURL)); 915c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); 916c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 917c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Navigate to another page. 918c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) const base::FilePath::CharType* kEmptyFile = FILE_PATH_LITERAL("empty.html"); 919c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) GURL file_url(ui_test_utils::GetTestUrl(base::FilePath( 920c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::FilePath::kCurrentDirectory), base::FilePath(kEmptyFile))); 921c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ui_test_utils::NavigateToURL(browser(), file_url); 922c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 923c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ClickOnView(VIEW_ID_TAB_CONTAINER); 924c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 925c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Navigate back. Should focus the location bar. 926c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 927c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::WindowedNotificationObserver back_nav_observer( 928c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::NOTIFICATION_NAV_ENTRY_COMMITTED, 929c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::NotificationService::AllSources()); 930c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chrome::GoBack(browser(), CURRENT_TAB); 931c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) back_nav_observer.Wait(); 932c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 933c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 934c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_TRUE(IsViewFocused(VIEW_ID_OMNIBOX)); 935c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 936c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) // Navigate forward. Shouldn't focus the location bar. 937c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) ClickOnView(VIEW_ID_TAB_CONTAINER); 938c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) { 939c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::WindowedNotificationObserver forward_nav_observer( 940c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::NOTIFICATION_NAV_ENTRY_COMMITTED, 941c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) content::NotificationService::AllSources()); 942c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) chrome::GoForward(browser(), CURRENT_TAB); 943c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) forward_nav_observer.Wait(); 944c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) } 945c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 946c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) EXPECT_FALSE(IsViewFocused(VIEW_ID_OMNIBOX)); 947c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)} 948c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) 9495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace 950