// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #include #include #include "base/test/test_file_util.h" #include "base/utf_string_conversions.h" #include "base/win/scoped_bstr.h" #include "base/win/scoped_variant.h" #include "base/win/windows_version.h" #include "chrome/common/url_constants.h" #include "chrome_frame/test/chrome_frame_test_utils.h" #include "chrome_frame/test/chrome_frame_ui_test_utils.h" #include "chrome_frame/test/mock_ie_event_sink_actions.h" #include "chrome_frame/test/mock_ie_event_sink_test.h" #include "testing/gmock_mutant.h" using testing::_; using testing::InSequence; using testing::StrCaseEq; using testing::StrEq; namespace chrome_frame_test { // This parameterized test fixture uses the MockIEEventSink and is used by // UI-related tests. class FullTabUITest : public MockIEEventSinkTest, public testing::TestWithParam { public: FullTabUITest() {} virtual void SetUp() { // These are UI-related tests, so we do not care about the exact requests // and navigations that occur. server_mock_.ExpectAndServeAnyRequests(GetParam()); ie_mock_.ExpectAnyNavigations(); } }; // Instantiate each test case for the IE case and for CF meta tag case. // It does not seem too useful to also run the CF http header case since these // are UI, not navigation tests. INSTANTIATE_TEST_CASE_P(IE, FullTabUITest, testing::Values(CFInvocation::None())); INSTANTIATE_TEST_CASE_P(CF, FullTabUITest, testing::Values(CFInvocation::MetaTag())); // Tests keyboard input. TEST_P(FullTabUITest, KeyboardInput) { if (!GetParam().invokes_cf()) { LOG(ERROR) << "Test not implemented for this configuration."; return; } std::wstring key_event_url = GetTestUrl(L"keyevent.html"); const char* input = "Chrome"; EXPECT_CALL(ie_mock_, OnLoad(GetParam().invokes_cf(), StrEq(key_event_url))) .WillOnce(PostCharMessagesToRenderer(&ie_mock_, input)); EXPECT_CALL(ie_mock_, OnMessage(StrCaseEq(UTF8ToWide(input)), _, _)) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(key_event_url); } // Tests keyboard shortcuts for back and forward. // http://code.google.com/p/chromium/issues/detail?id=114058 TEST_P(FullTabUITest, DISABLED_KeyboardBackForward) { if (IsWorkstationLocked()) { LOG(ERROR) << "This test cannot be run in a locked workstation."; return; } std::wstring page1 = GetSimplePageUrl(); std::wstring page2 = GetLinkPageUrl(); bool in_cf = GetParam().invokes_cf(); InSequence expect_in_sequence_for_scope; // This test performs the following steps. // 1. Launches IE and navigates to page1 // 2. It then navigates to page2 // 3. Sends the VK_BACK keystroke to IE, which should navigate back to // page 1 // 4. Sends the Shift + VK_BACK keystroke to IE which should navigate // forward to page2 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page1))) .WillOnce(Navigate(&ie_mock_, page2)); short bkspace = VkKeyScanA(VK_BACK); // NOLINT EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page2))) .WillOnce(testing::DoAll( SetFocusToRenderer(&ie_mock_), DelaySendScanCode(&loop_, base::TimeDelta::FromSeconds(1), bkspace, simulate_input::NONE))); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page1))) .WillOnce(testing::DoAll( SetFocusToRenderer(&ie_mock_), DelaySendScanCode(&loop_, base::TimeDelta::FromSeconds(1), bkspace, simulate_input::SHIFT))); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page2))) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIENavigateAndLoop(page1, kChromeFrameVeryLongNavigationTimeout); } // Tests new window behavior with ctrl+N. // Flaky due to DelaySendChar; see http://crbug.com/124244. TEST_P(FullTabUITest, FLAKY_CtrlN) { if (IsWorkstationLocked()) { LOG(ERROR) << "This test cannot be run in a locked workstation."; return; } bool is_cf = GetParam().invokes_cf(); if (!is_cf) { LOG(ERROR) << "Test not implemented for this configuration."; return; } // Ideally we want to use a ie_mock_ to watch for finer grained // events for New Window, but for Crl+N we don't get any // OnNewWindowX notifications. :( MockWindowObserver win_observer_mock; const char* kNewWindowTitlePattern = "*Internet Explorer*"; EXPECT_CALL(ie_mock_, OnLoad(is_cf, StrEq(GetSimplePageUrl()))) .WillOnce(testing::DoAll( WatchWindow(&win_observer_mock, kNewWindowTitlePattern, ""), SetFocusToRenderer(&ie_mock_), DelaySendChar(&loop_, base::TimeDelta::FromSeconds(1), 'n', simulate_input::CONTROL))); // Watch for new window. It appears that the window close message cannot be // reliably delivered immediately upon receipt of the window open event. EXPECT_CALL(win_observer_mock, OnWindowOpen(_)) .Times(testing::AtMost(2)) .WillOnce(CloseBrowserMock(&ie_mock_)) .WillOnce(testing::Return()); EXPECT_CALL(win_observer_mock, OnWindowClose(_)) .Times(testing::AtMost(2)); LaunchIENavigateAndLoop(GetSimplePageUrl(), kChromeFrameVeryLongNavigationTimeout); } // Test that Ctrl+F opens the Find dialog. // Flaky due to DelaySendChar; see http://crbug.com/124244. TEST_P(FullTabUITest, FLAKY_CtrlF) { if (IsWorkstationLocked()) { LOG(ERROR) << "This test cannot be run in a locked workstation."; return; } bool is_cf = GetParam().invokes_cf(); if (!is_cf) { LOG(ERROR) << "Test not implemented for this configuration."; return; } server_mock_.ExpectAndServeAnyRequests(CFInvocation::MetaTag()); MockWindowObserver win_observer_mock; InSequence expect_in_sequence_for_scope; const char* kFindDialogCaption = "Find"; EXPECT_CALL(ie_mock_, OnLoad(IN_CF, StrEq(GetSimplePageUrl()))) .WillOnce(testing::DoAll( WatchWindow(&win_observer_mock, kFindDialogCaption, ""), SetFocusToRenderer(&ie_mock_), DelaySendChar(&loop_, base::TimeDelta::FromMilliseconds(1500), 'f', simulate_input::CONTROL))); EXPECT_CALL(win_observer_mock, OnWindowOpen(_)) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIENavigateAndLoop(GetSimplePageUrl(), kChromeFrameVeryLongNavigationTimeout); } // Test that ctrl+r does cause a refresh. // Flaky due to DelaySendChar; see http://crbug.com/124244. TEST_P(FullTabUITest, FLAKY_CtrlR) { if (IsWorkstationLocked()) { LOG(ERROR) << "This test cannot be run in a locked workstation."; return; } EXPECT_CALL(server_mock_, Get(_, UrlPathEq(GetSimplePageUrl()), _)) .Times(testing::AtMost(2)) .WillRepeatedly(SendResponse(&server_mock_, GetParam())); EXPECT_CALL(ie_mock_, OnLoad(GetParam().invokes_cf(), StrEq(GetSimplePageUrl()))) .Times(testing::AtMost(2)) .WillOnce(testing::DoAll( SetFocusToRenderer(&ie_mock_), DelaySendChar(&loop_, base::TimeDelta::FromSeconds(1), 'r', simulate_input::CONTROL), DelayCloseBrowserMock( &loop_, base::TimeDelta::FromSeconds(4), &ie_mock_))) .WillRepeatedly(testing::Return()); LaunchIENavigateAndLoop(GetSimplePageUrl(), kChromeFrameVeryLongNavigationTimeout); } // Test window close with ctrl+w. // Flaky due to DelaySendChar; see http://crbug.com/124244. TEST_P(FullTabUITest, FLAKY_CtrlW) { if (IsWorkstationLocked()) { LOG(ERROR) << "This test cannot be run in a locked workstation."; return; } EXPECT_CALL(ie_mock_, OnLoad(GetParam().invokes_cf(), StrEq(GetSimplePageUrl()))) .WillOnce(testing::DoAll( SetFocusToRenderer(&ie_mock_), DelaySendChar(&loop_, base::TimeDelta::FromSeconds(1), 'w', simulate_input::CONTROL))); LaunchIENavigateAndLoop(GetSimplePageUrl(), kChromeFrameVeryLongNavigationTimeout); } // Test address bar navigation with Alt+d and URL. // Flaky due to TypeUrlInAddressBar; see http://crbug.com/124244. TEST_P(FullTabUITest, FLAKY_AltD) { if (IsWorkstationLocked()) { LOG(ERROR) << "This test cannot be run in a locked workstation."; return; } EXPECT_CALL(ie_mock_, OnLoad(GetParam().invokes_cf(), StrEq(GetSimplePageUrl()))) .WillOnce(testing::DoAll( SetFocusToRenderer(&ie_mock_), TypeUrlInAddressBar(&loop_, GetLinkPageUrl(), base::TimeDelta::FromMilliseconds(1500)))); EXPECT_CALL(ie_mock_, OnLoad(GetParam().invokes_cf(), StrEq(GetLinkPageUrl()))) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIENavigateAndLoop(GetSimplePageUrl(), kChromeFrameVeryLongNavigationTimeout); } // Tests that the renderer has focus after navigation. // Flaky, see http://crbug.com/90791 . TEST_P(FullTabUITest, DISABLED_RendererHasFocus) { EXPECT_CALL(ie_mock_, OnLoad(GetParam().invokes_cf(), StrEq(GetSimplePageUrl()))) .WillOnce(testing::DoAll( ExpectRendererHasFocus(&ie_mock_), CloseBrowserMock(&ie_mock_))); LaunchIEAndNavigate(GetSimplePageUrl()); } // Tests that view source works. TEST_P(FullTabUITest, ViewSource) { // Please see http://code.google.com/p/chromium/issues/detail?id=60987 // for more information on why this test is disabled for Vista with IE7. if (base::win::GetVersion() == base::win::VERSION_VISTA && GetInstalledIEVersion() == IE_7) { LOG(INFO) << "Not running test on Vista with IE7"; return; } bool in_cf = GetParam().invokes_cf(); if (!in_cf) { LOG(ERROR) << "Test not implemented for this configuration."; return; } MockIEEventSink view_source_mock; view_source_mock.ExpectAnyNavigations(); InSequence expect_in_sequence_for_scope; // After navigation invoke view soruce action using IWebBrowser2::ExecWB VARIANT empty = base::win::ScopedVariant::kEmptyVariant; EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetSimplePageUrl()))) .WillOnce(DelayExecCommand( &ie_mock_, &loop_, base::TimeDelta(), &CGID_MSHTML, static_cast(IDM_VIEWSOURCE), OLECMDEXECOPT_DONTPROMPTUSER, &empty, &empty)); // Expect notification for view-source window, handle new window event // and attach a new ie_mock_ to the received web browser std::wstring view_source_url; view_source_url += UTF8ToWide(chrome::kViewSourceScheme); view_source_url += L":"; view_source_url += GetSimplePageUrl(); std::wstring url_in_new_window = kChromeProtocolPrefix; url_in_new_window += view_source_url; ie_mock_.ExpectNewWindow(&view_source_mock); // For some reason this happens occasionally at least on XP IE7. EXPECT_CALL(view_source_mock, OnLoad(IN_IE, StrEq(url_in_new_window))) .Times(testing::AtMost(1)); EXPECT_CALL(view_source_mock, OnLoad(in_cf, StrEq(view_source_url))) .WillOnce(testing::DoAll( VerifyAddressBarUrlWithGcf(&view_source_mock), CloseBrowserMock(&view_source_mock))); EXPECT_CALL(view_source_mock, OnQuit()) .Times(testing::AtMost(1)) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(GetSimplePageUrl()); } void NavigateToCurrentUrl(MockIEEventSink* mock) { IWebBrowser2* browser = mock->event_sink()->web_browser2(); DCHECK(browser); base::win::ScopedBstr bstr; HRESULT hr = browser->get_LocationURL(bstr.Receive()); EXPECT_HRESULT_SUCCEEDED(hr); if (SUCCEEDED(hr)) { DCHECK(bstr.Length()); VARIANT empty = base::win::ScopedVariant::kEmptyVariant; hr = browser->Navigate(bstr, &empty, &empty, &empty, &empty); EXPECT_HRESULT_SUCCEEDED(hr); } } // Tests that Chrome gets re-instantiated after crash if we reload via // the address bar or via a new navigation. TEST_P(FullTabUITest, TabCrashReload) { using testing::DoAll; if (!GetParam().invokes_cf()) { LOG(ERROR) << "Test needs CF."; return; } MockPropertyNotifySinkListener prop_listener; InSequence expect_in_sequence_for_scope; EXPECT_CALL(ie_mock_, OnLoad(_, StrEq(GetSimplePageUrl()))) .WillOnce(DoAll( ExpectRendererHasFocus(&ie_mock_), ExpectDocumentReadystate(&ie_mock_, READYSTATE_COMPLETE), ConnectDocPropNotifySink(&ie_mock_, &prop_listener), KillChromeFrameProcesses())); EXPECT_CALL(prop_listener, OnChanged(DISPID_READYSTATE)) .WillOnce(DoAll( ExpectDocumentReadystate(&ie_mock_, READYSTATE_UNINITIALIZED), DelayNavigateToCurrentUrl( &ie_mock_, &loop_, base::TimeDelta::FromMilliseconds(10)))); EXPECT_CALL(ie_mock_, OnLoad(_, StrEq(GetSimplePageUrl()))) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(GetSimplePageUrl()); } // Tests if Chrome gets restarted after a crash by just refreshing the document. // DISABLED as per bug http://crbug.com/99317 (one of the failures is a // timeout, which marking as FLAKY or FAILS won't mask). TEST_P(FullTabUITest, DISABLED_TabCrashRefresh) { using testing::DoAll; if (!GetParam().invokes_cf()) { LOG(ERROR) << "Test needs CF."; return; } MockPropertyNotifySinkListener prop_listener; InSequence expect_in_sequence_for_scope; EXPECT_CALL(ie_mock_, OnLoad(_, StrEq(GetSimplePageUrl()))) .WillOnce(DoAll( ExpectRendererHasFocus(&ie_mock_), ExpectDocumentReadystate(&ie_mock_, READYSTATE_COMPLETE), ConnectDocPropNotifySink(&ie_mock_, &prop_listener), KillChromeFrameProcesses())); VARIANT empty = base::win::ScopedVariant::kEmptyVariant; EXPECT_CALL(prop_listener, OnChanged(/*DISPID_READYSTATE*/_)) .WillOnce(DoAll( DisconnectDocPropNotifySink(&prop_listener), ExpectDocumentReadystate(&ie_mock_, READYSTATE_UNINITIALIZED), DelayExecCommand( &ie_mock_, &loop_, base::TimeDelta::FromMilliseconds(10), static_cast(NULL), OLECMDID_REFRESH, 0, &empty, &empty))); EXPECT_CALL(ie_mock_, OnLoad(_, StrEq(GetSimplePageUrl()))) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(GetSimplePageUrl()); } // Test that window.print() on a page results in the native Windows print dialog // appearing rather than Chrome's in-page print preview. TEST_P(FullTabUITest, WindowPrintOpensNativePrintDialog) { std::wstring window_print_url(GetTestUrl(L"window_print.html")); std::wstring window_print_title(L"window.print"); const bool is_cf = GetParam().invokes_cf(); MockWindowObserver win_observer_mock; // When the page is loaded, start watching for the Print dialog to appear. EXPECT_CALL(ie_mock_, OnLoad(is_cf, StrEq(window_print_url))) .WillOnce(WatchWindow(&win_observer_mock, "Print", "")); // When the print dialog opens, close it. EXPECT_CALL(win_observer_mock, OnWindowOpen(_)) .WillOnce(DoCloseWindow()); // When the print dialog closes, close the browser. EXPECT_CALL(win_observer_mock, OnWindowClose(_)) .WillOnce(CloseBrowserMock(&ie_mock_)); // Launch IE and navigate to the window_print.html page, which will // window.print() immediately after loading. LaunchIEAndNavigate(window_print_url); } // Test fixture for tests related to the context menu UI. Since the context // menus for CF and IE are different, these tests are not parameterized. class ContextMenuTest : public MockIEEventSinkTest, public testing::Test { public: ContextMenuTest(): kTextFieldInitValue(L"SomeInitializedTextValue") {} virtual void SetUp() { context_menu_page_url = GetTestUrl(L"context_menu.html"); context_menu_page_title = L"context menu"; // Clear clipboard to make sure there is no effect from previous tests. SetClipboardText(L""); // These are UI-related tests, so we do not care about the exact // navigations that occur. ie_mock_.ExpectAnyNavigations(); EXPECT_CALL(ie_mock_, OnLoad(_, _)).Times(testing::AnyNumber()); EXPECT_CALL(acc_observer_, OnAccDocLoad(_)).Times(testing::AnyNumber()); } // Common helper function for "Save xxx As" tests. void DoSaveAsTest(const wchar_t* role, const wchar_t* menu_item_name, const wchar_t* file_ext) { server_mock_.ExpectAndServeAnyRequests(CFInvocation::MetaTag()); MockWindowObserver win_observer_mock; InSequence expect_in_sequence_for_scope; // Open 'Save As' dialog. const char* kSaveDlgCaption = "Save As"; EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(L"Save As download test"))) .WillOnce(testing::DoAll( WatchWindow(&win_observer_mock, kSaveDlgCaption, ""), AccRightClick(AccObjectMatcher(L"", role)))); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(AccLeftClick(AccObjectMatcher(menu_item_name))); // Get safe download name using temporary file. FilePath temp_file_path; ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path)); ASSERT_TRUE(file_util::DieFileDie(temp_file_path, false)); temp_file_path = temp_file_path.ReplaceExtension(file_ext); AccObjectMatcher file_name_box(L"File name:", L"editable text"); EXPECT_CALL(win_observer_mock, OnWindowOpen(_)) .WillOnce(testing::DoAll( AccSendCharMessage(file_name_box, L'a'), AccSetValue(file_name_box, temp_file_path.value()), AccDoDefaultAction(AccObjectMatcher(L"Save", L"push button")))); EXPECT_CALL(win_observer_mock, OnWindowClose(_)) .WillOnce(CloseWhenFileSaved(&ie_mock_, temp_file_path, 8000)); LaunchIENavigateAndLoop(GetTestUrl(L"save_as_context_menu.html"), kChromeFrameVeryLongNavigationTimeout); ASSERT_TRUE(file_util::DieFileDie(temp_file_path, false)); } protected: // Html page that holds a text field for context menu testing. std::wstring context_menu_page_url; // Title of said html page. std::wstring context_menu_page_title; // This is the text value used to test cut/copy/paste etc. const std::wstring kTextFieldInitValue; testing::NiceMock acc_observer_; }; // Test reloading from the context menu. TEST_F(ContextMenuTest, CFReload) { server_mock_.ExpectAndServeAnyRequests(CFInvocation::MetaTag()); InSequence expect_in_sequence_for_scope; EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(GetSimplePageTitle()))) .WillOnce(OpenContextMenuAsync()); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(AccLeftClick(AccObjectMatcher(L"Reload"))); EXPECT_CALL(ie_mock_, OnLoad(IN_CF, StrEq(GetSimplePageUrl()))) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(GetSimplePageUrl()); } // Test view source from the context menu. TEST_F(ContextMenuTest, CFViewSource) { // Please see http://code.google.com/p/chromium/issues/detail?id=60987 // for more information on why this test is disabled for Vista with IE7. if (base::win::GetVersion() == base::win::VERSION_VISTA && GetInstalledIEVersion() == IE_7) { LOG(INFO) << "Not running test on Vista with IE7"; return; } server_mock_.ExpectAndServeAnyRequests(CFInvocation::MetaTag()); MockIEEventSink view_source_mock; view_source_mock.ExpectAnyNavigations(); InSequence expect_in_sequence_for_scope; // View the page source. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(GetSimplePageTitle()))) .WillOnce(OpenContextMenuAsync()); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(AccLeftClick(AccObjectMatcher(L"View page source"))); // Expect notification for view-source window, handle new window event // and attach a new ie_mock_ to the received web browser std::wstring view_source_url; view_source_url += UTF8ToWide(chrome::kViewSourceScheme); view_source_url += L":"; view_source_url += GetSimplePageUrl(); std::wstring url_in_new_window = kChromeProtocolPrefix; url_in_new_window += view_source_url; ie_mock_.ExpectNewWindow(&view_source_mock); // For some reason this happens occasionally at least on XP IE7 and Win7 IE8. EXPECT_CALL(view_source_mock, OnLoad(IN_IE, StrEq(url_in_new_window))) .Times(testing::AtMost(1)); EXPECT_CALL(view_source_mock, OnLoad(IN_CF, StrEq(view_source_url))) .WillOnce(testing::DoAll( VerifyAddressBarUrlWithGcf(&view_source_mock), CloseBrowserMock(&view_source_mock))); EXPECT_CALL(view_source_mock, OnQuit()) .Times(testing::AtMost(1)) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(GetSimplePageUrl()); } TEST_F(ContextMenuTest, DISABLED_CFPageInfo) { server_mock_.ExpectAndServeAnyRequests(CFInvocation::MetaTag()); MockWindowObserver win_observer_mock; InSequence expect_in_sequence_for_scope; // View page information. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(GetSimplePageTitle()))) .WillOnce(testing::DoAll( WatchWindow(&win_observer_mock, "", "Chrome_WidgetWin_*"), OpenContextMenuAsync())); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(AccLeftClick(AccObjectMatcher(L"View page info"))); EXPECT_CALL(win_observer_mock, OnWindowOpen(_)).Times(1); // Expect page info dialog to pop up. Dismiss the dialog with 'Esc' key EXPECT_CALL(win_observer_mock, OnWindowOpen(_)) .WillOnce(DoCloseWindow()); EXPECT_CALL(win_observer_mock, OnWindowClose(_)).Times(1); EXPECT_CALL(win_observer_mock, OnWindowClose(_)) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(GetSimplePageUrl()); } TEST_F(ContextMenuTest, CFInspector) { server_mock_.ExpectAndServeAnyRequests(CFInvocation::MetaTag()); MockWindowObserver win_observer_mock; InSequence expect_in_sequence_for_scope; // Open developer tools. // Devtools begins life with "Untitled" caption and it changes // later to the 'Developer Tools - form. const char* kPageInfoCaptionPattern = "Untitled*"; EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(GetSimplePageTitle()))) .WillOnce(testing::DoAll( WatchWindow(&win_observer_mock, kPageInfoCaptionPattern, ""), OpenContextMenuAsync())); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(AccLeftClick(AccObjectMatcher(L"Inspect element"))); EXPECT_CALL(win_observer_mock, OnWindowOpen(_)) .WillOnce(DelayDoCloseWindow(5000)); // wait to catch possible crash EXPECT_CALL(win_observer_mock, OnWindowClose(_)) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIENavigateAndLoop(GetSimplePageUrl(), kChromeFrameVeryLongNavigationTimeout); } // http://code.google.com/p/chromium/issues/detail?id=83114 TEST_F(ContextMenuTest, DISABLED_CFSavePageAs) { // Please see http://code.google.com/p/chromium/issues/detail?id=60987 // for more information on why this test is disabled for Vista with IE7. if (base::win::GetVersion() == base::win::VERSION_VISTA && GetInstalledIEVersion() == IE_7) { LOG(INFO) << "Not running test on Vista with IE7"; return; } ASSERT_NO_FATAL_FAILURE(DoSaveAsTest(L"", L"Save as...", L".html")); } // http://code.google.com/p/chromium/issues/detail?id=83114 TEST_F(ContextMenuTest, DISABLED_CFSaveLinkAs) { // Please see http://code.google.com/p/chromium/issues/detail?id=60987 // for more information on why this test is disabled for Vista with IE7. if (base::win::GetVersion() == base::win::VERSION_VISTA && GetInstalledIEVersion() == IE_7) { LOG(INFO) << "Not running test on Vista with IE7"; return; } ASSERT_NO_FATAL_FAILURE(DoSaveAsTest(L"link", L"Save link as...", L".zip")); } // This tests that the about:version page can be opened via the CF context menu. TEST_F(ContextMenuTest, CFAboutVersionLoads) { // Please see http://code.google.com/p/chromium/issues/detail?id=60987 // for more information on why this test is disabled for Vista with IE7. if (base::win::GetVersion() == base::win::VERSION_VISTA && GetInstalledIEVersion() == IE_7) { LOG(INFO) << "Not running test on Vista with IE7"; return; } server_mock_.ExpectAndServeAnyRequests(CFInvocation::MetaTag()); const wchar_t* kAboutVersionUrl = L"gcf:about:version"; const wchar_t* kAboutVersionWithoutProtoUrl = L"about:version"; MockIEEventSink new_window_mock; new_window_mock.ExpectAnyNavigations(); InSequence expect_in_sequence_for_scope; EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(GetSimplePageTitle()))) .WillOnce(OpenContextMenuAsync()); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(AccLeftClick(AccObjectMatcher(L"About*"))); ie_mock_.ExpectNewWindow(&new_window_mock); // For some reason this happens occasionally at least on Win7 IE8. EXPECT_CALL(new_window_mock, OnLoad(IN_IE, StrEq(kAboutVersionUrl))) .Times(testing::AtMost(1)); EXPECT_CALL(new_window_mock, OnLoad(IN_CF, StrEq(kAboutVersionWithoutProtoUrl))) .WillOnce(testing::DoAll( VerifyAddressBarUrlWithGcf(&new_window_mock), CloseBrowserMock(&new_window_mock))); EXPECT_CALL(new_window_mock, OnQuit()) .Times(testing::AtMost(1)) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(GetSimplePageUrl()); } TEST_F(ContextMenuTest, IEOpen) { server_mock_.ExpectAndServeAnyRequests(CFInvocation::None()); InSequence expect_in_sequence_for_scope; // Open the link through the context menu. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(GetLinkPageTitle()))) .WillOnce(AccRightClick(AccObjectMatcher(L"", L"link"))); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(AccLeftClick(AccObjectMatcher(L"Open"))); EXPECT_CALL(ie_mock_, OnLoad(IN_IE, StrEq(GetSimplePageUrl()))) .WillOnce(testing::DoAll( VerifyAddressBarUrl(&ie_mock_), CloseBrowserMock(&ie_mock_))); LaunchIEAndNavigate(GetLinkPageUrl()); } TEST_F(ContextMenuTest, IEOpenInNewWindow) { // See crbug.com/64794. if (GetInstalledIEVersion() == IE_7) { LOG(INFO) << "Not running test with IE7"; return; } server_mock_.ExpectAndServeAnyRequests(CFInvocation::None()); MockIEEventSink new_window_mock; new_window_mock.ExpectAnyNavigations(); InSequence expect_in_sequence_for_scope; // Open the link in a new window. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(GetLinkPageTitle()))) .WillOnce(AccRightClick(AccObjectMatcher(L"", L"link"))); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(AccLeftClick(AccObjectMatcher(L"Open in New Window"))); ie_mock_.ExpectNewWindow(&new_window_mock); EXPECT_CALL(new_window_mock, OnLoad(IN_IE, StrEq(GetSimplePageUrl()))) // TODO(kkania): Verifying the address bar is flaky with this, at least // on XP ie6. Fix. .WillOnce(CloseBrowserMock(&new_window_mock)); EXPECT_CALL(new_window_mock, OnQuit()) .Times(testing::AtMost(1)) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(GetLinkPageUrl()); } // Test Back/Forward from context menu. TEST_F(ContextMenuTest, IEBackForward) { server_mock_.ExpectAndServeAnyRequests(CFInvocation::None()); std::wstring page1 = GetLinkPageUrl(); std::wstring title1 = GetLinkPageTitle(); std::wstring page2 = GetSimplePageUrl(); std::wstring title2 = GetSimplePageTitle(); InSequence expect_in_sequence_for_scope; // Navigate to second page. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(title1))) .WillOnce(Navigate(&ie_mock_, page2)); // Go back. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(title2))) .WillOnce(testing::DoAll( VerifyPageLoad(&ie_mock_, IN_IE, page2), OpenContextMenuAsync())); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(AccLeftClick(AccObjectMatcher(L"Back"))); // Go forward. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(title1))) .WillOnce(testing::DoAll( VerifyPageLoad(&ie_mock_, IN_IE, page1), OpenContextMenuAsync())); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(AccLeftClick(AccObjectMatcher(L"Forward"))); EXPECT_CALL(ie_mock_, OnLoad(IN_IE, StrEq(page2))) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(page1); } // Test CF link context menu - Open link in new window. // Failing intermittently on IE6/7. See crbug.com/64794. TEST_F(ContextMenuTest, DISABLED_CFOpenLinkInNewWindow) { server_mock_.ExpectAndServeAnyRequests(CFInvocation::MetaTag()); MockIEEventSink new_window_mock; new_window_mock.ExpectAnyNavigations(); // Invoke 'Open link in new window' context menu item. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(GetLinkPageTitle()))) .Times(testing::AtMost(2)) .WillOnce(AccRightClick(AccObjectMatcher(L"", L"link"))) .WillOnce(testing::Return()); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(AccLeftClick(AccObjectMatcher(L"Open link in new window*"))); ie_mock_.ExpectNewWindow(&new_window_mock); EXPECT_CALL(new_window_mock, OnLoad(IN_CF, StrEq(GetSimplePageUrl()))) .WillOnce(CloseBrowserMock(&new_window_mock)); EXPECT_CALL(new_window_mock, OnQuit()) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(GetLinkPageUrl()); } // Test CF link context menu - Copy link address. TEST_F(ContextMenuTest, CFCopyLinkAddress) { server_mock_.ExpectAndServeAnyRequests(CFInvocation::MetaTag()); // Invoke 'Copy link address' context menu item. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(GetLinkPageTitle()))) .WillOnce(AccRightClick(AccObjectMatcher(L"", L"link"))); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(testing::DoAll( AccLeftClick(AccObjectMatcher(L"Copy link address*")), CloseBrowserMock(&ie_mock_))); LaunchIEAndNavigate(GetLinkPageUrl()); EXPECT_STREQ(GetSimplePageUrl().c_str(), GetClipboardText().c_str()); } // Test CF text field context menu - cut. // Times out sporadically http://crbug.com/119660. TEST_F(ContextMenuTest, FLAKY_CFTxtFieldCut) { server_mock_.ExpectAndServeAnyRequests(CFInvocation::MetaTag()); AccObjectMatcher txtfield_matcher(L"", L"editable text"); // Invoke "Cut" context menu item of text field. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(context_menu_page_title))) .WillOnce(testing::DoAll( AccRightClick(txtfield_matcher), AccWatchForOneValueChange(&acc_observer_, txtfield_matcher))); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(AccLeftClick(AccObjectMatcher(L"Cut*"))); // Verify that text field is empty after cut operation. EXPECT_CALL(acc_observer_, OnAccValueChange(_, _, StrEq(L""))) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(context_menu_page_url); // Verify that the text value has been cut to clipboard. EXPECT_STREQ(kTextFieldInitValue.c_str(), GetClipboardText().c_str()); } // Test CF text field context menu - copy. // Times out sporadically http://crbug.com/119660. TEST_F(ContextMenuTest, FLAKY_CFTxtFieldCopy) { server_mock_.ExpectAndServeAnyRequests(CFInvocation::MetaTag()); AccObjectMatcher txtfield_matcher(L"", L"editable text"); // Invoke "Copy" context menu item of text field. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(context_menu_page_title))) .WillOnce(testing::DoAll( AccRightClick(txtfield_matcher), AccWatchForOneValueChange(&acc_observer_, txtfield_matcher))); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(testing::DoAll( AccLeftClick(AccObjectMatcher(L"Copy*")), CloseBrowserMock(&ie_mock_))); // Verify that there is no change on text field value after copy operation. EXPECT_CALL(acc_observer_, OnAccValueChange(_, _, _)) .Times(testing::AtMost(0)); LaunchIEAndNavigate(context_menu_page_url); // Verify that the text value has been copied to clipboard. EXPECT_STREQ(kTextFieldInitValue.c_str(), GetClipboardText().c_str()); } // Test CF text field context menu - paste. // Times out sporadically http://crbug.com/119660. TEST_F(ContextMenuTest, FLAKY_CFTxtFieldPaste) { server_mock_.ExpectAndServeAnyRequests(CFInvocation::MetaTag()); AccObjectMatcher txtfield_matcher(L"", L"editable text"); // Invoke "Paste" context menu item of text field. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(context_menu_page_title))) .WillOnce(testing::DoAll( AccRightClick(txtfield_matcher), AccWatchForOneValueChange(&acc_observer_, txtfield_matcher))); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(AccLeftClick(AccObjectMatcher(L"Paste*"))); // Verify that value has been pasted to text field. EXPECT_CALL(acc_observer_, OnAccValueChange(_, _, StrEq(kTextFieldInitValue))) .WillOnce(CloseBrowserMock(&ie_mock_)); // Set some text value to clipboard, this is to emulate the 'copy' action. SetClipboardText(kTextFieldInitValue); LaunchIEAndNavigate(context_menu_page_url); } // Test CF text field context menu - delete. // Times out sporadically http://crbug.com/119660. TEST_F(ContextMenuTest, FLAKY_CFTxtFieldDelete) { server_mock_.ExpectAndServeAnyRequests(CFInvocation::MetaTag()); AccObjectMatcher txtfield_matcher(L"", L"editable text"); // Invoke 'Delete' context menu item of text field. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(context_menu_page_title))) .WillOnce(testing::DoAll( AccRightClick(txtfield_matcher), AccWatchForOneValueChange(&acc_observer_, txtfield_matcher))); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(AccLeftClick(AccObjectMatcher(L"Delete*"))); // Verify that value has been deleted from text field. EXPECT_CALL(acc_observer_, OnAccValueChange(_, _, StrEq(L""))) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(context_menu_page_url); } // Test CF text field context menu - select all. TEST_F(ContextMenuTest, CFTxtFieldSelectAll) { server_mock_.ExpectAndServeAnyRequests(CFInvocation::MetaTag()); // Invoke 'Select all' context menu item of text field. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(context_menu_page_title))) .WillOnce(AccRightClick(AccObjectMatcher(L"", L"editable text"))); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(testing::DoAll( AccLeftClick(AccObjectMatcher(L"Select all*")), PostMessageToCF(&ie_mock_, L"selectall"))); // Client side script verifies that the text field value has been selected, // then send 'OK' message. EXPECT_CALL(ie_mock_, OnMessage(testing::StrCaseEq(L"OK"), _, _)) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(context_menu_page_url + L"?action=selectall"); } // Test CF text field context menu - undo. // Times out sporadically http://crbug.com/119660. TEST_F(ContextMenuTest, FLAKY_CFTxtFieldUndo) { server_mock_.ExpectAndServeAnyRequests(CFInvocation::MetaTag()); AccObjectMatcher txtfield_matcher(L"", L"editable text"); // Change the value of text field to 'A'. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(context_menu_page_title))) .WillOnce(testing::DoAll( AccWatchForOneValueChange(&acc_observer_, txtfield_matcher), AccSendCharMessage(txtfield_matcher, L'A'))); // Bring up the context menu once the value has changed. EXPECT_CALL(acc_observer_, OnAccValueChange(_, _, StrEq(L"A"))) .WillOnce(AccRightClick(txtfield_matcher)); // Then select "Undo". EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(testing::DoAll( AccWatchForOneValueChange(&acc_observer_, txtfield_matcher), AccLeftClick(AccObjectMatcher(L"Undo*")))); // Verify that value has been reset to initial value after undo operation. EXPECT_CALL(acc_observer_, OnAccValueChange(_, _, StrEq(kTextFieldInitValue))) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(context_menu_page_url); } // Test CF text field context menu - redo. // Times out sporadically http://crbug.com/119660. TEST_F(ContextMenuTest, FLAKY_CFTxtFieldRedo) { server_mock_.ExpectAndServeAnyRequests(CFInvocation::MetaTag()); AccObjectMatcher txtfield_matcher(L"", L"editable text"); InSequence expect_in_sequence_for_scope; // Change text field from its initial value to 'A'. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(context_menu_page_title))) .WillOnce(testing::DoAll( AccWatchForOneValueChange(&acc_observer_, txtfield_matcher), AccSendCharMessage(txtfield_matcher, L'A'))); // Bring up the context menu. EXPECT_CALL(acc_observer_, OnAccValueChange(_, _, StrEq(L"A"))) .WillOnce(AccRightClick(txtfield_matcher)); // Select "Undo" EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(testing::DoAll( AccWatchForOneValueChange(&acc_observer_, txtfield_matcher), AccLeftClick(AccObjectMatcher(L"Undo*")))); // After undo operation is done, bring up the context menu again. EXPECT_CALL(acc_observer_, OnAccValueChange(_, _, StrEq(kTextFieldInitValue))) .WillOnce(AccRightClick(txtfield_matcher)); // Select "Redo" EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(testing::DoAll( AccWatchForOneValueChange(&acc_observer_, txtfield_matcher), AccLeftClick(AccObjectMatcher(L"Redo*")))); // Verify that text field value is reset to its changed value 'A' and exit. EXPECT_CALL(acc_observer_, OnAccValueChange(_, _, StrEq(L"A"))) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(context_menu_page_url); } // Disabled because it seems to hang, causing the test process to timeout and // be killed; see http://crbug.com/121097. TEST_F(ContextMenuTest, DISABLED_CFBackForward) { std::wstring page1 = GetLinkPageUrl(); std::wstring title1 = GetLinkPageTitle(); std::wstring page2 = GetSimplePageUrl(); std::wstring title2 = GetSimplePageTitle(); std::wstring page3 = GetTestUrl(L"anchor.html"); std::wstring title3 = GetAnchorPageTitle(); server_mock_.ExpectAndServeRequestWithCardinality( CFInvocation::MetaTag(), page1, testing::Exactly(2)); server_mock_.ExpectAndServeRequestWithCardinality( CFInvocation::None(), page2, testing::Exactly(3)); server_mock_.ExpectAndServeRequestWithCardinality( CFInvocation::MetaTag(), page3, testing::Exactly(2)); InSequence expect_in_sequence_for_scope; // Navigate to second page. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(title1))) .WillOnce(testing::DoAll( VerifyPageLoad(&ie_mock_, IN_CF, page1), Navigate(&ie_mock_, page2))); // Navigate to third page. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(title2))) .WillOnce(testing::DoAll( VerifyPageLoad(&ie_mock_, IN_IE, page2), Navigate(&ie_mock_, page3))); // Go back. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(title3))) .WillOnce(testing::DoAll( VerifyPageLoad(&ie_mock_, IN_CF, page3), OpenContextMenuAsync())); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(AccLeftClick(AccObjectMatcher(L"Back"))); // Go back EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(title2))) .WillOnce(testing::DoAll( VerifyPageLoad(&ie_mock_, IN_IE, page2), OpenContextMenuAsync())); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(AccLeftClick(AccObjectMatcher(L"Back"))); // Go forward. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(title1))) .WillOnce(testing::DoAll( VerifyPageLoad(&ie_mock_, IN_CF, page1), OpenContextMenuAsync())); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(AccLeftClick(AccObjectMatcher(L"Forward"))); // Go forward. EXPECT_CALL(acc_observer_, OnAccDocLoad(TabContentsTitleEq(title2))) .WillOnce(testing::DoAll( VerifyPageLoad(&ie_mock_, IN_IE, page2), OpenContextMenuAsync())); EXPECT_CALL(acc_observer_, OnMenuPopup(_)) .WillOnce(AccLeftClick(AccObjectMatcher(L"Forward"))); EXPECT_CALL(ie_mock_, OnLoad(IN_CF, StrEq(page3))) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIENavigateAndLoop(page1, kChromeFrameVeryLongNavigationTimeout); } } // namespace chrome_frame_test