| // Copyright (c) 2011 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 <mshtmcid.h> |
| #include <string> |
| |
| #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<CFInvocation> { |
| 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. |
| TEST_P(FullTabUITest, FLAKY_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_, 1000, bkspace, simulate_input::NONE))); |
| |
| EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page1))) |
| .WillOnce(testing::DoAll( |
| SetFocusToRenderer(&ie_mock_), |
| DelaySendScanCode(&loop_, 1000, bkspace, simulate_input::SHIFT))); |
| |
| EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page2))) |
| .WillOnce(CloseBrowserMock(&ie_mock_)); |
| |
| LaunchIENavigateAndLoop(page1, |
| kChromeFrameVeryLongNavigationTimeoutInSeconds); |
| } |
| |
| // Tests new window behavior with ctrl+N. |
| TEST_P(FullTabUITest, 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_, 1000, '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(), |
| kChromeFrameVeryLongNavigationTimeoutInSeconds); |
| } |
| |
| // Test that Ctrl+F opens the Find dialog. |
| TEST_P(FullTabUITest, 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_, 1500, 'f', simulate_input::CONTROL))); |
| |
| EXPECT_CALL(win_observer_mock, OnWindowOpen(_)) |
| .WillOnce(CloseBrowserMock(&ie_mock_)); |
| |
| LaunchIENavigateAndLoop(GetSimplePageUrl(), |
| kChromeFrameVeryLongNavigationTimeoutInSeconds); |
| } |
| |
| // Test that ctrl+r does cause a refresh. |
| TEST_P(FullTabUITest, 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_, 1000, 'r', simulate_input::CONTROL), |
| DelayCloseBrowserMock(&loop_, 4000, &ie_mock_))) |
| .WillRepeatedly(testing::Return()); |
| |
| LaunchIENavigateAndLoop(GetSimplePageUrl(), |
| kChromeFrameVeryLongNavigationTimeoutInSeconds); |
| } |
| |
| // Test window close with ctrl+w. |
| TEST_P(FullTabUITest, 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_, 1000, 'w', simulate_input::CONTROL))); |
| |
| LaunchIENavigateAndLoop(GetSimplePageUrl(), |
| kChromeFrameVeryLongNavigationTimeoutInSeconds); |
| } |
| |
| // Test address bar navigation with Alt+d and URL. |
| TEST_P(FullTabUITest, 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(), 1500))); |
| |
| EXPECT_CALL(ie_mock_, OnLoad(GetParam().invokes_cf(), |
| StrEq(GetLinkPageUrl()))) |
| .WillOnce(CloseBrowserMock(&ie_mock_)); |
| |
| LaunchIENavigateAndLoop(GetSimplePageUrl(), |
| kChromeFrameVeryLongNavigationTimeoutInSeconds); |
| } |
| |
| // Tests that the renderer has focus after navigation. |
| TEST_P(FullTabUITest, 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_, 0, &CGID_MSHTML, |
| static_cast<OLECMDID>(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_, 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. |
| TEST_P(FullTabUITest, 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_, 10, static_cast<GUID*>(NULL), |
| OLECMDID_REFRESH, 0, &empty, &empty))); |
| |
| EXPECT_CALL(ie_mock_, OnLoad(_, StrEq(GetSimplePageUrl()))) |
| .WillOnce(CloseBrowserMock(&ie_mock_)); |
| |
| LaunchIEAndNavigate(GetSimplePageUrl()); |
| } |
| |
| // 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"); |
| // 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(_)) |
| .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"), |
| kChromeFrameVeryLongNavigationTimeoutInSeconds); |
| 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; |
| // This is the text value used to test cut/copy/paste etc. |
| const std::wstring kTextFieldInitValue; |
| |
| testing::NiceMock<MockAccEventObserver> 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(_)) |
| .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(_)) |
| .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(_)) |
| .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 - <url> form. |
| const char* kPageInfoCaptionPattern = "Untitled*"; |
| EXPECT_CALL(acc_observer_, OnAccDocLoad(_)) |
| .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(), |
| kChromeFrameVeryLongNavigationTimeoutInSeconds); |
| } |
| |
| // http://code.google.com/p/chromium/issues/detail?id=83114 |
| TEST_F(ContextMenuTest, FLAKY_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(_)) |
| .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 throught the context menu. |
| EXPECT_CALL(acc_observer_, OnAccDocLoad(_)) |
| .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(_)) |
| .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 page2 = GetSimplePageUrl(); |
| InSequence expect_in_sequence_for_scope; |
| |
| // Navigate to second page. |
| EXPECT_CALL(acc_observer_, OnAccDocLoad(_)) |
| .WillOnce(Navigate(&ie_mock_, page2)); |
| |
| // Go back. |
| EXPECT_CALL(acc_observer_, OnAccDocLoad(_)) |
| .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(_)) |
| .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, FLAKY_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(_)) |
| .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(_)) |
| .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. |
| TEST_F(ContextMenuTest, 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(_)) |
| .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. |
| TEST_F(ContextMenuTest, 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(_)) |
| .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. |
| TEST_F(ContextMenuTest, 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(_)) |
| .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. |
| TEST_F(ContextMenuTest, 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(_)) |
| .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(_)) |
| .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. |
| TEST_F(ContextMenuTest, CFTxtFieldUndo) { |
| server_mock_.ExpectAndServeAnyRequests(CFInvocation::MetaTag()); |
| AccObjectMatcher txtfield_matcher(L"", L"editable text"); |
| |
| // Change the value of text field to 'A', then invoke 'Undo' context menu item |
| // of text field. |
| EXPECT_CALL(acc_observer_, OnAccDocLoad(_)) |
| .WillOnce(testing::DoAll( |
| AccSendCharMessage(txtfield_matcher, L'A'), |
| AccRightClick(txtfield_matcher))); |
| 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. |
| TEST_F(ContextMenuTest, CFTxtFieldRedo) { |
| server_mock_.ExpectAndServeAnyRequests(CFInvocation::MetaTag()); |
| AccObjectMatcher txtfield_matcher(L"", L"editable text"); |
| InSequence expect_in_sequence_for_scope; |
| |
| // Change text field value to 'A', then undo it. |
| EXPECT_CALL(acc_observer_, OnAccDocLoad(_)) |
| .WillOnce(testing::DoAll( |
| AccSendCharMessage(txtfield_matcher, L'A'), |
| AccRightClick(txtfield_matcher))); |
| EXPECT_CALL(acc_observer_, OnMenuPopup(_)) |
| .WillOnce(testing::DoAll( |
| AccWatchForOneValueChange(&acc_observer_, txtfield_matcher), |
| AccLeftClick(AccObjectMatcher(L"Undo*")))); |
| |
| // After undo operation is done, invoke 'Redo' context menu item. |
| EXPECT_CALL(acc_observer_, OnAccValueChange(_, _, StrEq(kTextFieldInitValue))) |
| .WillOnce(testing::DoAll( |
| AccRightClick(txtfield_matcher), |
| AccWatchForOneValueChange(&acc_observer_, txtfield_matcher))); |
| EXPECT_CALL(acc_observer_, OnMenuPopup(_)) |
| .WillOnce(AccLeftClick(AccObjectMatcher(L"Redo*"))); |
| |
| // After redo operation is done, verify that text field value is reset to its |
| // changed value 'A'. |
| EXPECT_CALL(acc_observer_, OnAccValueChange(_, _, StrEq(L"A"))) |
| .WillOnce(CloseBrowserMock(&ie_mock_)); |
| |
| LaunchIEAndNavigate(context_menu_page_url); |
| } |
| |
| TEST_F(ContextMenuTest, CFBackForward) { |
| std::wstring page1 = GetLinkPageUrl(); |
| std::wstring page2 = GetSimplePageUrl(); |
| std::wstring page3 = GetTestUrl(L"anchor.html"); |
| |
| 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(_)) |
| .WillOnce(testing::DoAll( |
| VerifyPageLoad(&ie_mock_, IN_CF, page1), |
| Navigate(&ie_mock_, page2))); |
| |
| // Navigate to third page. |
| EXPECT_CALL(acc_observer_, OnAccDocLoad(_)) |
| .WillOnce(testing::DoAll( |
| VerifyPageLoad(&ie_mock_, IN_IE, page2), |
| Navigate(&ie_mock_, page3))); |
| |
| // Go back. |
| EXPECT_CALL(acc_observer_, OnAccDocLoad(_)) |
| .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(_)) |
| .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(_)) |
| .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(_)) |
| .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, |
| kChromeFrameVeryLongNavigationTimeoutInSeconds); |
| } |
| |
| } // namespace chrome_frame_test |