// 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 "base/test/test_file_util.h" #include "base/win/scoped_comptr.h" #include "base/win/windows_version.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 "net/http/http_util.h" // Needed for CreateFunctor. #define GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING #include "testing/gmock_mutant.h" using testing::InSequence; using testing::StrEq; using testing::_; namespace chrome_frame_test { // Test fixture for navigation-related tests. Each test is run thrice: IE, CF // with meta tag invocation, and CF with http header invocation. This is // accomplished by using gTest's parameterized test. class FullTabNavigationTest : public MockIEEventSinkTest, public testing::TestWithParam { public: FullTabNavigationTest() {} }; // Instantiate each test case. Instead of doing in one statement, it is split // into three so gTest prints nicer names. INSTANTIATE_TEST_CASE_P(IE, FullTabNavigationTest, testing::Values( CFInvocation(CFInvocation::NONE))); INSTANTIATE_TEST_CASE_P(MetaTag, FullTabNavigationTest, testing::Values( CFInvocation(CFInvocation::META_TAG))); INSTANTIATE_TEST_CASE_P(HttpHeader, FullTabNavigationTest, testing::Values( CFInvocation(CFInvocation::HTTP_HEADER))); // This tests navigation to a typed URL. TEST_P(FullTabNavigationTest, TypeUrl) { MockAccEventObserver acc_observer; EXPECT_CALL(acc_observer, OnAccDocLoad(_)).Times(testing::AnyNumber()); AccObjectMatcher address_matcher(L"Address*", L"editable text"); AccObjectMatcher go_matcher(L"Go*", L"push button"); ie_mock_.ExpectNavigation(IN_IE, GetSimplePageUrl()); server_mock_.ExpectAndServeRequest(CFInvocation::None(), GetSimplePageUrl()); // Enter the new url into the address bar. EXPECT_CALL(ie_mock_, OnLoad(IN_IE, StrEq(GetSimplePageUrl()))) .WillOnce(testing::DoAll( AccSetValueInBrowser(&ie_mock_, address_matcher, GetAnchorPageUrl(0)), AccWatchForOneValueChange(&acc_observer, address_matcher))); // Click the go button once the address has changed. EXPECT_CALL(acc_observer, OnAccValueChange(_, _, GetAnchorPageUrl(0))) .WillOnce(AccLeftClickInBrowser(&ie_mock_, go_matcher)); bool in_cf = GetParam().invokes_cf(); ie_mock_.ExpectNavigation(in_cf, GetAnchorPageUrl(0)); server_mock_.ExpectAndServeRequest(GetParam(), GetAnchorPageUrl(0)); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(0)))) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(GetSimplePageUrl()); } // This tests navigation to a typed URL containing an fragment. TEST_P(FullTabNavigationTest, TypeAnchorUrl) { MockAccEventObserver acc_observer; EXPECT_CALL(acc_observer, OnAccDocLoad(_)).Times(testing::AnyNumber()); AccObjectMatcher address_matcher(L"Address*", L"editable text"); AccObjectMatcher go_matcher(L"Go*", L"push button"); ie_mock_.ExpectNavigation(IN_IE, GetSimplePageUrl()); server_mock_.ExpectAndServeRequest(CFInvocation::None(), GetSimplePageUrl()); // Enter the new url into the address bar. EXPECT_CALL(ie_mock_, OnLoad(IN_IE, StrEq(GetSimplePageUrl()))) .WillOnce(testing::DoAll( AccSetValueInBrowser(&ie_mock_, address_matcher, GetAnchorPageUrl(1)), AccWatchForOneValueChange(&acc_observer, address_matcher))); // Click the go button once the address has changed. EXPECT_CALL(acc_observer, OnAccValueChange(_, _, GetAnchorPageUrl(1))) .WillOnce(AccLeftClickInBrowser(&ie_mock_, go_matcher)); bool in_cf = GetParam().invokes_cf(); ie_mock_.ExpectNavigation(in_cf, GetAnchorPageUrl(1)); server_mock_.ExpectAndServeRequest(GetParam(), GetAnchorPageUrl(1)); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(1)))) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(GetSimplePageUrl()); } // Tests refreshing causes a page load. TEST_P(FullTabNavigationTest, Refresh) { if (GetInstalledIEVersion() == IE_7) { LOG(ERROR) << "Test disabled for this configuration."; return; } bool in_cf = GetParam().invokes_cf(); server_mock_.ExpectAndServeAnyRequests(GetParam()); InSequence expect_in_sequence_for_scope; ie_mock_.ExpectNavigation(IN_IE, GetSimplePageUrl()); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetSimplePageUrl()))) .WillOnce(DelayRefresh(&ie_mock_, &loop_, base::TimeDelta())); if (in_cf) { EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetSimplePageUrl()))) .WillOnce(CloseBrowserMock(&ie_mock_)); } else { // For some reason IE still requests the resource again, but does not // trigger another load. EXPECT_CALL(server_mock_, Get(_, UrlPathEq(GetSimplePageUrl()), _)) .WillOnce(CloseBrowserMock(&ie_mock_)); } LaunchIEAndNavigate(GetSimplePageUrl()); } // Test that multiple back and forward requests work. // TODO(tsepez): http://crbug.com/83133 TEST_P(FullTabNavigationTest, DISABLED_MultipleBackForward) { std::wstring page1 = GetSimplePageUrl(); std::wstring page2 = GetLinkPageUrl(); std::wstring page3 = GetAnchorPageUrl(0); bool in_cf = GetParam().invokes_cf(); server_mock_.ExpectAndServeAnyRequests(GetParam()); InSequence expect_in_sequence_for_scope; // Navigate to url 2 after the previous navigation is complete. ie_mock_.ExpectNavigation(in_cf, page1); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page1))) .WillOnce(testing::DoAll( VerifyAddressBarUrl(&ie_mock_), Navigate(&ie_mock_, page2))); // Navigate to url 3 after the previous navigation is complete. ie_mock_.ExpectNavigation(in_cf, page2); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page2))) .WillOnce(testing::DoAll( VerifyAddressBarUrl(&ie_mock_), Navigate(&ie_mock_, page3))); // We have reached url 3 and have two back entries for url 1 & 2. // Go back to url 2 now. ie_mock_.ExpectNavigation(in_cf, page3); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page3))) .WillOnce(testing::DoAll( VerifyAddressBarUrl(&ie_mock_), DelayGoBack(&ie_mock_, &loop_, base::TimeDelta()))); // We have reached url 2 and have 1 back & 1 forward entries for url 1 & 3. // Go back to url 1 now. ie_mock_.ExpectNavigation(in_cf, page2); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page2))) .WillOnce(testing::DoAll( VerifyAddressBarUrl(&ie_mock_), DelayGoBack(&ie_mock_, &loop_, base::TimeDelta()))); // We have reached url 1 and have 0 back & 2 forward entries for url 2 & 3. // Go forward to url 2 now. ie_mock_.ExpectNavigation(in_cf, page1); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page1))) .WillOnce(testing::DoAll( VerifyAddressBarUrl(&ie_mock_), DelayGoForward(&ie_mock_, &loop_, base::TimeDelta()))); // We have reached url 2 and have 1 back & 1 forward entries for url 1 & 3. // Go forward to url 3 now. ie_mock_.ExpectNavigation(in_cf, page2); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page2))) .WillOnce(testing::DoAll( VerifyAddressBarUrl(&ie_mock_), DelayGoForward(&ie_mock_, &loop_, base::TimeDelta()))); // We have reached url 2 and have 1 back & 1 forward entries for url 1 & 3. ie_mock_.ExpectNavigation(in_cf, page3); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page3))) .WillOnce(testing::DoAll( VerifyAddressBarUrl(&ie_mock_), CloseBrowserMock(&ie_mock_))); LaunchIENavigateAndLoop(page1, kChromeFrameLongNavigationTimeout * 2); } // Test multiple back and forward operations among urls with anchors. TEST_P(FullTabNavigationTest, BackForwardAnchor) { std::wstring title(GetAnchorPageTitle()); bool in_cf = GetParam().invokes_cf(); ie_mock_.ExpectAnyNavigations(); server_mock_.ExpectAndServeAnyRequests(GetParam()); MockAccEventObserver acc_observer; EXPECT_CALL(acc_observer, OnAccDocLoad(_)).Times(testing::AnyNumber()); // Navigate to anchor 1. // Back/Forward state at this point: // Back: 0 // Forward: 0 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(0)))) .Times(testing::AtMost(1)); EXPECT_CALL(acc_observer, OnAccDocLoad(TabContentsTitleEq(title))) .WillOnce(AccDoDefaultAction(AccObjectMatcher(L"*1", L"link"))) .RetiresOnSaturation(); InSequence expect_in_sequence_for_scope; // Navigate to anchor 2 after the previous navigation is complete // Back/Forward state at this point: // Back: 1 (kAnchorUrl) // Forward: 0 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(1)))) .WillOnce(testing::DoAll( VerifyAddressBarUrl(&ie_mock_), AccDoDefaultActionInRenderer(&ie_mock_, AccObjectMatcher(L"*2", L"link")))); // Navigate to anchor 3 after the previous navigation is complete // Back/Forward state at this point: // Back: 2 (kAnchorUrl, kAnchor1Url) // Forward: 0 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(2)))) .WillOnce(testing::DoAll( VerifyAddressBarUrl(&ie_mock_), AccDoDefaultActionInRenderer(&ie_mock_, AccObjectMatcher(L"*3", L"link")))); // We will reach anchor 3 once the navigation is complete, // then go back to anchor 2 // Back/Forward state at this point: // Back: 3 (kAnchorUrl, kAnchor1Url, kAnchor2Url) // Forward: 0 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(3)))) .WillOnce(testing::DoAll( VerifyAddressBarUrl(&ie_mock_), DelayGoBack(&ie_mock_, &loop_, base::TimeDelta()))); // We will reach anchor 2 once the navigation is complete, // then go back to anchor 1 // Back/Forward state at this point: // Back: 3 (kAnchorUrl, kAnchor1Url, kAnchor2Url) // Forward: 1 (kAnchor3Url) EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(2)))) .WillOnce(testing::DoAll( VerifyAddressBarUrl(&ie_mock_), DelayGoBack(&ie_mock_, &loop_, base::TimeDelta()))); // We will reach anchor 1 once the navigation is complete, // now go forward to anchor 2 // Back/Forward state at this point: // Back: 2 (kAnchorUrl, kAnchor1Url) // Forward: 2 (kAnchor2Url, kAnchor3Url) EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(1)))) .WillOnce(testing::DoAll( VerifyAddressBarUrl(&ie_mock_), DelayGoForward(&ie_mock_, &loop_, base::TimeDelta()))); // We have reached anchor 2, go forward to anchor 3 again // Back/Forward state at this point: // Back: 3 (kAnchorUrl, kAnchor1Url, kAnchor2Url) // Forward: 1 (kAnchor3Url) EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(2)))) .WillOnce(testing::DoAll( VerifyAddressBarUrl(&ie_mock_), DelayGoForward(&ie_mock_, &loop_, base::TimeDelta()))); // We have gone a few steps back and forward, this should be enough for now. EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(3)))) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(GetAnchorPageUrl(0)); } // Test that a user cannot navigate to a restricted site and that the security // dialog appears. TEST_P(FullTabNavigationTest, RestrictedSite) { // Add the server to restricted sites zone. base::win::ScopedComPtr security_manager; HRESULT hr = security_manager.CreateInstance(CLSID_InternetSecurityManager); ASSERT_HRESULT_SUCCEEDED(hr); hr = security_manager->SetZoneMapping(URLZONE_UNTRUSTED, GetTestUrl(L"").c_str(), SZM_CREATE); EXPECT_CALL(ie_mock_, OnFileDownload(_, _)).Times(testing::AnyNumber()); server_mock_.ExpectAndServeAnyRequests(GetParam()); MockWindowObserver win_observer_mock; // If the page is loaded in mshtml, then IE allows the page to be loaded // and just shows 'Restricted sites' in the status bar. if (!GetParam().invokes_cf()) { ie_mock_.ExpectNavigation(IN_IE, GetSimplePageUrl()); EXPECT_CALL(ie_mock_, OnLoad(IN_IE, StrEq(GetSimplePageUrl()))) .Times(1) .WillOnce(CloseBrowserMock(&ie_mock_)); } else { // If the page is being loaded in chrome frame then we will see // a security dialog. const char* kAlertDlgCaption = "Security Alert"; win_observer_mock.WatchWindow(kAlertDlgCaption, ""); EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, testing::HasSubstr(GetSimplePageUrl())), _, _, _, _, _)) .Times(testing::AtMost(2)); EXPECT_CALL(ie_mock_, OnNavigateComplete2(_, testing::Field(&VARIANT::bstrVal, StrEq(GetSimplePageUrl())))) .Times(testing::AtMost(1)); EXPECT_CALL(win_observer_mock, OnWindowOpen(_)) .Times(1) .WillOnce(DoCloseWindow()); EXPECT_CALL(win_observer_mock, OnWindowClose(_)) .Times(1) .WillOnce(CloseBrowserMock(&ie_mock_)); } LaunchIEAndNavigate(GetSimplePageUrl()); ASSERT_HRESULT_SUCCEEDED(security_manager->SetZoneMapping(URLZONE_UNTRUSTED, GetTestUrl(L"").c_str(), SZM_DELETE)); } // This test checks if window.open calls with target blank issued for a // different domain make it back to IE instead of completing the navigation // within Chrome. We validate this by initiating a navigation to a non existent // url which ensures we would get an error during navigation. // Marking this disabled as it leaves behind Chrome processes, at least on // IE 6 XP (http://crbug.com/48732). TEST_P(FullTabNavigationTest, DISABLED_JavascriptWindowOpenDifferentDomain) { if (!GetParam().invokes_cf() || GetInstalledIEVersion() == IE_7) { LOG(ERROR) << "Test disabled for this configuration."; return; } std::wstring parent_url = GetWindowOpenUrl(L"http://www.nonexistent.com"); MockAccEventObserver acc_observer; MockIEEventSink new_window_mock; ie_mock_.ExpectAnyNavigations(); new_window_mock.ExpectAnyNavigations(); server_mock_.ExpectAndServeAnyRequests(GetParam()); EXPECT_CALL(acc_observer, OnAccDocLoad(_)).Times(testing::AnyNumber()); EXPECT_CALL(ie_mock_, OnLoad(GetParam().invokes_cf(), StrEq(parent_url))); EXPECT_CALL(acc_observer, OnAccDocLoad(TabContentsTitleEq(GetWindowOpenTitle()))) .WillOnce(AccLeftClick(AccObjectMatcher())); ie_mock_.ExpectNewWindow(&new_window_mock); EXPECT_CALL(new_window_mock, OnNavigateError(_, _, _, _, _)) .Times(1) .WillOnce(CloseBrowserMock(&new_window_mock)); EXPECT_CALL(new_window_mock, OnLoad(_, _)) .Times(testing::AtMost(1)); EXPECT_CALL(new_window_mock, OnQuit()) .Times(1) .WillOnce(CloseBrowserMock(&ie_mock_)); // OnNavigateError can take a long time to fire. LaunchIENavigateAndLoop(parent_url, kChromeFrameLongNavigationTimeout * 4); ASSERT_TRUE(new_window_mock.event_sink()->web_browser2() != NULL); } // Tests that the parent window can successfully close its popup through // the javascript close method. TEST_P(FullTabNavigationTest, JavascriptWindowOpenCanClose) { // 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; } std::wstring parent_url = GetWindowOpenUrl(L"simple.html"); MockAccEventObserver acc_observer; MockIEEventSink new_window_mock; ie_mock_.ExpectAnyNavigations(); new_window_mock.ExpectAnyNavigations(); server_mock_.ExpectAndServeAnyRequests(GetParam()); EXPECT_CALL(acc_observer, OnAccDocLoad(_)).Times(testing::AnyNumber()); // Tell the page to open the popup. Some versions of IE will prevent a popup // unless a click is involved. EXPECT_CALL(ie_mock_, OnLoad(GetParam().invokes_cf(), StrEq(parent_url))); EXPECT_CALL(acc_observer, OnAccDocLoad(TabContentsTitleEq(GetWindowOpenTitle()))) .WillOnce(AccLeftClick(AccObjectMatcher())); ie_mock_.ExpectNewWindow(&new_window_mock); EXPECT_CALL(new_window_mock, OnLoad(_, StrEq(GetSimplePageUrl()))) .Times(testing::AtMost(2)) .WillOnce(PostCharMessageToRenderer(&ie_mock_, 'C')) // close the popup .WillOnce(testing::Return()); EXPECT_CALL(new_window_mock, OnQuit()) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIENavigateAndLoop(parent_url, kChromeFrameLongNavigationTimeout * 2); } // Parameter for tests using the NavigationTransitionTest fixture. Includes two // pages, each with their own possible CF invocation. struct NavigationTransitionTestParameter { NavigationTransitionTestParameter(CFInvocation::Type type1, CFInvocation::Type type2) { page1_ = CFInvocation(type1); page2_ = CFInvocation(type2); } CFInvocation page1_; CFInvocation page2_; }; // Parameterized test fixture for tests which test navigation transitions // between two pages. class NavigationTransitionTest : public MockIEEventSinkTest, public testing::TestWithParam { public: NavigationTransitionTest() {} virtual void SetUp() { page1_ = GetParam().page1_; page2_ = GetParam().page2_; } protected: CFInvocation page1_; CFInvocation page2_; }; // This instantiates each parameterized test with some of the different CF // invocation methods. INSTANTIATE_TEST_CASE_P( IEToIE, NavigationTransitionTest, testing::Values(NavigationTransitionTestParameter( CFInvocation::NONE, CFInvocation::NONE))); INSTANTIATE_TEST_CASE_P( IEToMetaTag, NavigationTransitionTest, testing::Values(NavigationTransitionTestParameter( CFInvocation::NONE, CFInvocation::META_TAG))); INSTANTIATE_TEST_CASE_P( IEToHttpHeader, NavigationTransitionTest, testing::Values(NavigationTransitionTestParameter( CFInvocation::NONE, CFInvocation::HTTP_HEADER))); INSTANTIATE_TEST_CASE_P( CFToCF, NavigationTransitionTest, testing::Values(NavigationTransitionTestParameter( CFInvocation::META_TAG, CFInvocation::META_TAG))); INSTANTIATE_TEST_CASE_P( CFToIE, NavigationTransitionTest, testing::Values(NavigationTransitionTestParameter( CFInvocation::META_TAG, CFInvocation::NONE))); // Test window.open calls. TEST_P(NavigationTransitionTest, JavascriptWindowOpen) { // 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; } std::wstring parent_url = GetWindowOpenUrl(L"simple.html"); std::wstring new_window_url = GetSimplePageUrl(); MockAccEventObserver acc_observer; testing::StrictMock new_window_mock; EXPECT_CALL(acc_observer, OnAccDocLoad(_)).Times(testing::AnyNumber()); ie_mock_.ExpectNavigation(page1_.invokes_cf(), parent_url); server_mock_.ExpectAndServeRequest(page1_, parent_url); EXPECT_CALL(ie_mock_, OnLoad(page1_.invokes_cf(), StrEq(parent_url))); // Tell the page to open the popup. Some versions of IE will prevent a popup // unless a click is involved. EXPECT_CALL(acc_observer, OnAccDocLoad(TabContentsTitleEq(GetWindowOpenTitle()))) .WillOnce(AccLeftClick(AccObjectMatcher())); // If the parent window is in CF, the child should always load in CF since // the domain is the same. bool expect_cf = page1_.invokes_cf() || page2_.invokes_cf(); ie_mock_.ExpectNewWindow(&new_window_mock); new_window_mock.ExpectJavascriptWindowOpenNavigation(page1_.invokes_cf(), expect_cf, new_window_url); server_mock_.ExpectAndServeRequest(page2_, new_window_url); EXPECT_CALL(new_window_mock, OnLoad(expect_cf, StrEq(new_window_url))) .WillOnce(testing::DoAll( ValidateWindowSize(&new_window_mock, 10, 10, 250, 250), CloseBrowserMock(&new_window_mock))); EXPECT_CALL(new_window_mock, OnQuit()) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIENavigateAndLoop(parent_url, kChromeFrameLongNavigationTimeout * 2); } // Test redirection with window.location in Javascript. // Disabled because crashes IE occasionally: http://crbug.com/48849. TEST_P(NavigationTransitionTest, DISABLED_JavascriptRedirection) { std::wstring redirect_url = GetTestUrl(L"javascript_redirect.html"); ie_mock_.ExpectNavigation(page1_.invokes_cf(), redirect_url); server_mock_.ExpectAndServeRequest(page1_, redirect_url); EXPECT_CALL(ie_mock_, OnLoad(page1_.invokes_cf(), StrEq(redirect_url))) .WillOnce(VerifyAddressBarUrl(&ie_mock_)); ie_mock_.ExpectNavigation(page2_.invokes_cf(), GetSimplePageUrl()); server_mock_.ExpectAndServeRequest(page2_, GetSimplePageUrl()); EXPECT_CALL(ie_mock_, OnLoad(page2_.invokes_cf(), StrEq(GetSimplePageUrl()))) .WillOnce(testing::DoAll( VerifyAddressBarUrl(&ie_mock_), CloseBrowserMock(&ie_mock_))); LaunchIEAndNavigate(redirect_url); } // Test following a link. TEST_P(NavigationTransitionTest, FollowLink) { if (page1_.invokes_cf() && page2_.invokes_cf()) { // For some reason IE 7 and 8 send two BeforeNavigate events for the second // page for this case. All versions do not send the OnLoad event for the // second page if both pages are renderered in CF. LOG(ERROR) << "Test disabled for this configuration."; return; } MockAccEventObserver acc_observer; EXPECT_CALL(acc_observer, OnAccDocLoad(_)).Times(testing::AnyNumber()); ie_mock_.ExpectNavigation(page1_.invokes_cf(), GetLinkPageUrl()); // Two requests are made when going from CF to IE, at least on Win7 IE8. EXPECT_CALL(server_mock_, Get(_, UrlPathEq(GetLinkPageUrl()), _)) .Times(testing::Between(1, 2)) .WillRepeatedly(SendResponse(&server_mock_, page1_)); EXPECT_CALL(ie_mock_, OnLoad(page1_.invokes_cf(), StrEq(GetLinkPageUrl()))); EXPECT_CALL(acc_observer, OnAccDocLoad(TabContentsTitleEq(GetLinkPageTitle()))) .WillOnce(AccDoDefaultAction(AccObjectMatcher(L"", L"link"))) .RetiresOnSaturation(); ie_mock_.ExpectNavigation(page2_.invokes_cf(), GetSimplePageUrl()); server_mock_.ExpectAndServeRequest(page2_, GetSimplePageUrl()); EXPECT_CALL(ie_mock_, OnLoad(page2_.invokes_cf(), StrEq(GetSimplePageUrl()))) .WillOnce(testing::DoAll( VerifyAddressBarUrl(&ie_mock_), CloseBrowserMock(&ie_mock_))); LaunchIEAndNavigate(GetLinkPageUrl()); } // gMock matcher which tests if a url is blank. MATCHER(BlankUrl, "is \"\" or NULL") { return arg == NULL || wcslen(arg) == 0; } // Basic navigation test fixture which uses the MockIEEventSink. These tests // are not parameterized. class NavigationTest : public MockIEEventSinkTest, public testing::Test { public: NavigationTest() {} void TestDisAllowedUrl(const wchar_t* url) { // If a navigation fails then IE issues a navigation to an interstitial // page. Catch this to track navigation errors as the NavigateError // notification does not seem to fire reliably. EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, StrEq(url)), _, _, _, _, _)); EXPECT_CALL(ie_mock_, OnLoad(IN_IE, BlankUrl())) .Times(testing::AtMost(1)); EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, testing::StartsWith(L"res:")), _, _, _, _, _)); EXPECT_CALL(ie_mock_, OnFileDownload(VARIANT_TRUE, _)) .Times(testing::AnyNumber()) .WillRepeatedly(testing::Return()); EXPECT_CALL(ie_mock_, OnNavigateComplete2(_, testing::Field(&VARIANT::bstrVal, StrEq(url)))); // Although we expect a load event for this, we should never receive a // corresponding GET request. EXPECT_CALL(ie_mock_, OnLoad(IN_IE, StrEq(url))) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(url); } }; // Test navigation to a disallowed gcf: url with file scheme. // Times out sporadically; http://crbug.com/119718. TEST_F(NavigationTest, FLAKY_GcfProtocol1) { // Make sure that we are not accidently enabling gcf protocol. SetConfigBool(kAllowUnsafeURLs, false); TestDisAllowedUrl(L"gcf:file:///C:/"); } // Test navigation to a disallowed gcf: url with http scheme. TEST_F(NavigationTest, GcfProtocol2) { // Make sure that we are not accidently enabling gcf protocol. SetConfigBool(kAllowUnsafeURLs, false); TestDisAllowedUrl(L"gcf:http://www.google.com"); } // Test navigation to a disallowed gcf: url with https scheme. TEST_F(NavigationTest, GcfProtocol3) { // Make sure that we are not accidently enabling gcf protocol. SetConfigBool(kAllowUnsafeURLs, false); TestDisAllowedUrl(L"gcf:https://www.google.com"); } // NOTE: This test is currently disabled as we haven't finished implementing // support for this yet. The test (as written) works fine for IE. CF might // have a different set of requirements once we fully support this and hence // the test might need some refining before being enabled. TEST_F(NavigationTest, DISABLED_DownloadInNewWindow) { MockIEEventSink new_window_mock; std::wstring kDownloadFromNewWin = GetTestUrl(L"full_tab_download_from_new_window.html"); ie_mock_.ExpectNavigation(IN_CF, kDownloadFromNewWin); EXPECT_CALL(ie_mock_, OnNewWindow3(_, _, _, _, _)); EXPECT_CALL(ie_mock_, OnNewBrowserWindow(_, _)) .WillOnce(testing::WithArgs<0>(testing::Invoke(testing::CreateFunctor( &new_window_mock, &MockIEEventSink::Attach)))); EXPECT_CALL(new_window_mock, OnBeforeNavigate2(_, _, _, _, _, _, _)); EXPECT_CALL(new_window_mock, OnFileDownload(VARIANT_FALSE, _)) .Times(2) .WillRepeatedly(CloseBrowserMock(&new_window_mock)); EXPECT_CALL(new_window_mock, OnNavigateComplete2(_, _)); EXPECT_CALL(new_window_mock, OnQuit()).WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(kDownloadFromNewWin); } TEST_P(FullTabNavigationTest, FormPostBackForward) { bool in_cf = GetParam().invokes_cf(); // Navigate to the form-get.html page: // - First set focus to chrome renderer window // - Send over a character to the window. // - This should initiate a form post which eventually navigates to the // action.html page. // Navigate backwards from the action.html page and then navigate forward // from the form-get.html page. std::wstring kFormPostUrl = GetTestUrl(L"form-get.html"); std::wstring kFormPostActionUrl = GetTestUrl(L"action.html?field1=a&field2=b&submit=Submit"); std::wstring kFormPostTitle(L"ChromeFrame form submit test(GET method)"); MockAccEventObserver acc_observer; server_mock_.ExpectAndServeAnyRequests(GetParam()); EXPECT_CALL(acc_observer, OnAccDocLoad(_)).Times(testing::AnyNumber()); EXPECT_CALL(acc_observer, OnAccDocLoad(TabContentsTitleEq(kFormPostTitle))) .WillOnce(AccDoDefaultAction(AccObjectMatcher(L"Submit"))) .RetiresOnSaturation(); InSequence expect_in_sequence_for_scope; ie_mock_.ExpectNavigation(in_cf, kFormPostUrl); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kFormPostUrl))); ie_mock_.ExpectNavigationOptionalBefore(in_cf, kFormPostActionUrl); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kFormPostActionUrl))) .WillOnce(testing::DoAll( VerifyAddressBarUrl(&ie_mock_), DelayGoBack(&ie_mock_, &loop_, base::TimeDelta()))); ie_mock_.ExpectNavigation(in_cf, kFormPostUrl); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kFormPostUrl))) .WillOnce(testing::DoAll( VerifyAddressBarUrl(&ie_mock_), DelayGoForward(&ie_mock_, &loop_, base::TimeDelta()))); ie_mock_.ExpectNavigationOptionalBefore(in_cf, kFormPostActionUrl); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kFormPostActionUrl))) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(kFormPostUrl); } TEST_P(FullTabNavigationTest, CF_UnloadEventTest) { bool in_cf = GetParam().invokes_cf(); if (!in_cf) { LOG(ERROR) << "Test not yet implemented."; return; } std::wstring kUnloadEventTestUrl = GetTestUrl(L"fulltab_before_unload_event_test.html"); std::wstring kUnloadEventMainUrl = GetTestUrl(L"fulltab_before_unload_event_main.html"); server_mock_.ExpectAndServeAnyRequests(GetParam()); InSequence expect_in_sequence_for_scope; ie_mock_.ExpectNavigation(in_cf, kUnloadEventTestUrl); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kUnloadEventTestUrl))); ie_mock_.ExpectNavigationOptionalBefore(in_cf, kUnloadEventMainUrl); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kUnloadEventMainUrl))); EXPECT_CALL(ie_mock_, OnMessage(_, _, _)) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(kUnloadEventTestUrl); } // Fixture for ChromeFrame download tests. class FullTabDownloadTest : public MockIEEventSinkTest, public testing::TestWithParam { public: FullTabDownloadTest() {} }; void SaveOwnerWindow(HWND* owner_window, HWND window) { *owner_window = GetWindow(window, GW_OWNER); } void CloseWindow(HWND* window) { if (window) PostMessage(*window, WM_CLOSE, 0, 0); } // See bug http://crbug.com/36694 // This test does the following:- // Navigates IE to a URL which in ChromeFrame. // Performs a top level form post in the document // In response to the POST we send over an attachment via the // content-disposition header. // IE brings up a file open dialog in this context. // We bring up the Save dialog via accessibility and save the file // and validate that all is well. TEST_F(FullTabDownloadTest, CF_DownloadFileFromPost) { // 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) { if (GetInstalledIEVersion() == IE_7) { LOG(INFO) << "Not running test on Vista with IE7"; return; } else if (GetInstalledIEVersion() == IE_9) { LOG(INFO) << "Not running test on Vista/Windows 7 with IE9"; return; } } chrome_frame_test::MockWindowObserver download_watcher; download_watcher.WatchWindow("File Download", ""); chrome_frame_test::MockWindowObserver save_dialog_watcher; save_dialog_watcher.WatchWindow("Save As", ""); testing::StrictMock download_window_mock; EXPECT_CALL(server_mock_, Get(_, StrEq(L"/post_source.html"), _)).WillOnce( SendFast( "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n", "" "" " " " " "
" "
")); EXPECT_CALL(server_mock_, Post(_, StrEq(L"/post_target.html"), _)) .Times(2) .WillRepeatedly( SendFast( "HTTP/1.1 200 OK\r\n" "content-disposition: attachment;filename=\"hello.txt\"\r\n" "Content-Type: application/text\r\n" "Cache-Control: private\r\n", "hello")); // If you want to debug this action then you may need to // SendMessage(parent_window, WM_NCACTIVATE, TRUE, 0); // SendMessage(parent_window, WM_COMMAND, MAKEWPARAM(0x114B, BN_CLICKED), // control_window); // For the uninitiated, please debug IEFrame!CDialogActivateGuard::* EXPECT_CALL(download_watcher, OnWindowOpen(_)) .Times(2) .WillOnce(DelayAccDoDefaultAction( AccObjectMatcher(L"Save", L"push button"), 1000)) .WillOnce(testing::Return()); EXPECT_CALL(download_watcher, OnWindowClose(_)) .Times(testing::AnyNumber()); std::wstring src_url = server_mock_.Resolve(L"/post_source.html"); std::wstring tgt_url = server_mock_.Resolve(L"/post_target.html"); EXPECT_CALL(ie_mock_, OnFileDownload(_, _)).Times(testing::AnyNumber()); EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, StrEq(src_url)), _, _, _, _, _)); EXPECT_CALL(ie_mock_, OnNavigateComplete2(_, testing::Field(&VARIANT::bstrVal, StrEq(src_url)))); EXPECT_CALL(ie_mock_, OnLoad(true, StrEq(src_url))) .Times(testing::AnyNumber()); ie_mock_.ExpectNewWindow(&download_window_mock); EXPECT_CALL(ie_mock_, OnLoadError(StrEq(tgt_url))) .Times(testing::AnyNumber()); EXPECT_CALL(download_window_mock, OnFileDownload(_, _)) .Times(testing::AnyNumber()); EXPECT_CALL(download_window_mock, OnLoadError(StrEq(tgt_url))) .Times(testing::AtMost(1)); EXPECT_CALL(download_window_mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, StrEq(tgt_url)), _, _, _, _, _)); EXPECT_CALL(download_window_mock, OnLoad(false, _)); EXPECT_CALL(download_window_mock, OnQuit()).Times(testing::AtMost(1)); FilePath temp_file_path; ASSERT_TRUE(file_util::CreateTemporaryFile(&temp_file_path)); file_util::DieFileDie(temp_file_path, false); temp_file_path = temp_file_path.ReplaceExtension(L"txt"); file_util::DieFileDie(temp_file_path, false); AccObjectMatcher file_name_box(L"File name:", L"editable text"); HWND owner_window = NULL; EXPECT_CALL(save_dialog_watcher, OnWindowOpen(_)) .WillOnce(testing::DoAll( testing::Invoke(testing::CreateFunctor( SaveOwnerWindow, &owner_window)), AccSendCharMessage(file_name_box, L'a'), AccSetValue(file_name_box, temp_file_path.value()), AccDoDefaultAction(AccObjectMatcher(L"Save", L"push button")))); EXPECT_CALL(save_dialog_watcher, OnWindowClose(_)) .WillOnce(testing::DoAll( WaitForFileSave(temp_file_path, 2000), testing::InvokeWithoutArgs( testing::CreateFunctor(CloseWindow, &owner_window)), CloseBrowserMock(&ie_mock_))); LaunchIENavigateAndLoop(src_url, kChromeFrameVeryLongNavigationTimeout); std::string data; EXPECT_TRUE(file_util::ReadFileToString(temp_file_path, &data)); EXPECT_EQ("hello", data); file_util::DieFileDie(temp_file_path, false); } // Test fixture for testing if http header works for supported content types class HttpHeaderTest : public MockIEEventSinkTest, public testing::Test { public: HttpHeaderTest() {} void HeaderTestWithData(const char* content_type, const char* data) { const wchar_t* relative_url = L"/header_test"; const char* kHeaderFormat = "HTTP/1.1 200 OK\r\n" "Connection: close\r\n" "Content-Type: %s\r\n" "X-UA-Compatible: chrome=1\r\n"; std::string header = StringPrintf(kHeaderFormat, content_type); std::wstring url = server_mock_.Resolve(relative_url); EXPECT_CALL(server_mock_, Get(_, StrEq(relative_url), _)) .WillRepeatedly(SendFast(header, data)); InSequence expect_in_sequence_for_scope; ie_mock_.ExpectNavigation(IN_CF, url); EXPECT_CALL(ie_mock_, OnLoad(IN_CF, StrEq(url))) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIEAndNavigate(url); } }; const char* kXmlContent = "" "" "" "" "" ""; TEST_F(HttpHeaderTest, ApplicationXhtml) { HeaderTestWithData("application/xhtml+xml", kXmlContent); } TEST_F(HttpHeaderTest, ApplicationXml) { HeaderTestWithData("application/xml", kXmlContent); } TEST_F(HttpHeaderTest, TextXml) { HeaderTestWithData("text/xml", kXmlContent); } const char* kImageSvg = "" "" "" ""; TEST_F(HttpHeaderTest, DISABLED_ImageSvg) { HeaderTestWithData("image/svg", kImageSvg); } TEST_F(HttpHeaderTest, ImageSvgXml) { HeaderTestWithData("image/svg+xml", kImageSvg); } // Tests refreshing causes a page load. TEST_P(FullTabNavigationTest, RefreshContents) { bool in_cf = GetParam().invokes_cf(); if (!in_cf) { VLOG(1) << "Disabled for this configuration"; return; } const char kHeaders[] = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n" "X-UA-Compatible: chrome=1\r\nCache-control: no-cache\r\n"; const char kBody[] = "Hi there. Got new content?" ""; std::wstring src_url = server_mock_.Resolve(L"/refresh_src.html"); EXPECT_CALL(server_mock_, Get(_, StrEq(L"/refresh_src.html"), _)) .Times(2) .WillRepeatedly(SendFast(kHeaders, kBody)); EXPECT_CALL(ie_mock_, OnFileDownload(_, _)).Times(testing::AnyNumber()); EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, StrEq(src_url)), _, _, _, _, _)); EXPECT_CALL(ie_mock_, OnNavigateComplete2(_, testing::Field(&VARIANT::bstrVal, StrEq(src_url)))); EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(src_url))) .Times(2) .WillOnce(DelayRefresh( &ie_mock_, &loop_, base::TimeDelta::FromMilliseconds(50))) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIENavigateAndLoop(src_url, kChromeFrameVeryLongNavigationTimeout); } class FullTabSeleniumTest : public MockIEEventSinkTest, public testing::TestWithParam { public: FullTabSeleniumTest() : MockIEEventSinkTest(1337, L"127.0.0.1", GetSeleniumTestFolder()) {} }; ACTION(VerifySeleniumCoreTestResults) { int num_tests = 0; int failed_tests = 0; swscanf(arg0, L"%d/%d", &num_tests, &failed_tests); // Currently we run total 505 tests and 8 steps fail. // TODO(amit): send results as JSON, diagnose and eliminate failures. EXPECT_LE(failed_tests, 15) << "Expected failures: " << 15 << " Actual failures: " << failed_tests; EXPECT_GE(num_tests, 500) << "Expected to run: " << 500 << " tests." << " Actual number of tests run: " << num_tests; } // Crashes flakily: http://crbug.com/109114 // Tests refreshing causes a page load. TEST_F(FullTabSeleniumTest, DISABLED_Core) { // 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::HttpHeader()); std::wstring url = GetTestUrl(L"core/TestRunner.html"); // Expectations for TestRunner.html EXPECT_CALL(ie_mock_, OnFileDownload(_, _)).Times(testing::AnyNumber()); EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, testing::StartsWith(url)), _, _, _, _, _)) .Times(testing::AnyNumber()); EXPECT_CALL(ie_mock_, OnNavigateComplete2(_, testing::Field(&VARIANT::bstrVal, testing::StartsWith(url)))) .Times(testing::AnyNumber()); EXPECT_CALL(ie_mock_, OnLoad(true, testing::StartsWith(url))) .Times(testing::AnyNumber()); // Expectation for cookie test EXPECT_CALL(ie_mock_, OnLoadError(testing::StartsWith(url))) .Times(testing::AtMost(3)); // Expectations for popups std::wstring attach_url_prefix = GetTestUrl(L"?attach_external_tab&"); EXPECT_CALL(ie_mock_, OnNewWindow3(_, _, _, _, testing::StartsWith(attach_url_prefix))) .Times(testing::AnyNumber()); EXPECT_CALL(ie_mock_, OnNewBrowserWindow(_, testing::StartsWith(attach_url_prefix))) .Times(testing::AnyNumber()); // At the end the tests will post us a message. See _onTestSuiteComplete in // ...\src\data\selenium_core\core\scripts\selenium-testrunner.js EXPECT_CALL(ie_mock_, OnMessage(_, _, _)) .WillOnce(testing::DoAll(VerifySeleniumCoreTestResults(), CloseBrowserMock(&ie_mock_))); // Selenium tests take longer to finish, lets give it 2 mins. const base::TimeDelta kSeleniumTestTimeout = base::TimeDelta::FromMinutes(2); LaunchIENavigateAndLoop(url, kSeleniumTestTimeout); } // See bug http://code.google.com/p/chromium/issues/detail?id=64901 // This test does the following:- // Navigates IE to a non ChromeFrame URL. // Performs a top level form post in the document // In response to the POST send over a html document containing a meta tag // This would cause IE to switch to ChromeFrame. // Refresh the page in ChromeFrame. // This should bring up a confirmation dialog which we hit yes on. This should // reissue the top level post request in response to which the html content // containing the meta tag is sent again. TEST_F(FullTabDownloadTest, TopLevelPostReissueFromChromeFramePage) { chrome_frame_test::MockWindowObserver post_reissue_watcher; post_reissue_watcher.WatchWindow("Confirm Form Resubmission", ""); EXPECT_CALL(server_mock_, Get(_, StrEq(L"/post_source.html"), _)) .WillOnce(SendFast( "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n", "" "" " " " " "
" "
")); EXPECT_CALL(server_mock_, Post(_, StrEq(L"/post_target.html"), _)) .Times(2) .WillRepeatedly( SendFast( "HTTP/1.1 200 OK\r\n" "Content-Type: text/html\r\n", "" "" "" " Target page in ChromeFrame " "")); EXPECT_CALL(post_reissue_watcher, OnWindowOpen(_)) .WillOnce(DelayAccDoDefaultAction( AccObjectMatcher(L"Yes", L"push button"), 1000)); EXPECT_CALL(post_reissue_watcher, OnWindowClose(_)); std::wstring src_url = server_mock_.Resolve(L"/post_source.html"); std::wstring tgt_url = server_mock_.Resolve(L"/post_target.html"); EXPECT_CALL(ie_mock_, OnFileDownload(_, _)).Times(testing::AnyNumber()); EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, StrEq(src_url)), _, _, _, _, _)); EXPECT_CALL(ie_mock_, OnNavigateComplete2(_, testing::Field(&VARIANT::bstrVal, StrEq(src_url)))); EXPECT_CALL(ie_mock_, OnLoad(false, StrEq(src_url))); EXPECT_CALL(ie_mock_, OnLoad(true, StrEq(tgt_url))) .Times(2) .WillOnce(DelayRefresh( &ie_mock_, &loop_, base::TimeDelta::FromMilliseconds(50))) .WillOnce(CloseBrowserMock(&ie_mock_)); EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, StrEq(tgt_url)), _, _, _, _, _)) .Times(2); EXPECT_CALL(ie_mock_, OnNavigateComplete2(_, testing::Field(&VARIANT::bstrVal, StrEq(tgt_url)))) .Times(2); LaunchIENavigateAndLoop(src_url, kChromeFrameVeryLongNavigationTimeout); } MATCHER_P(UserAgentHeaderMatcher, ua_string, "") { std::string headers = arg.headers(); StringToUpperASCII(&headers); std::string ua_string_to_search = ua_string; StringToUpperASCII(&ua_string_to_search); net::HttpUtil::HeadersIterator it(headers.begin(), headers.end(), "\r\n"); while (it.GetNext()) { if (lstrcmpiA(it.name().c_str(), "User-Agent") == 0) { if (it.values().find(ua_string_to_search) != std::string::npos) return true; } } return false; } // Tests refreshing causes a page load and that the chrome frame user agent // string is appended to the UA in the incoming top level HTTP requests. TEST_P(FullTabNavigationTest, RefreshContentsUATest) { const char kBody[] = "" "Hi there. Got new content?" ""; std::string headers = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n" "Cache-control: no-cache\r\n"; bool in_cf = GetParam().invokes_cf(); if (in_cf) { headers.append("X-UA-Compatible: chrome=1\r\n"); } else { if (GetInstalledIEVersion() == IE_9) { LOG(ERROR) << "Test disabled for IE9"; return; } } std::wstring src_url = server_mock_.Resolve(L"/refresh_src.html"); if (in_cf) { // In the case of Chrome Frame, end the test when the second OnLoad is // fired. EXPECT_CALL(server_mock_, Get(_, StrEq(L"/refresh_src.html"), UserAgentHeaderMatcher("chromeframe"))) .Times(2) .WillRepeatedly(SendFast(headers, kBody)); } else { // In the case of IE, we never receive a second OnLoad event, so end the // test when the second request is made on the server. EXPECT_CALL(server_mock_, Get(_, StrEq(L"/refresh_src.html"), UserAgentHeaderMatcher("chromeframe"))) .Times(2) .WillOnce(SendFast(headers, kBody)) .WillOnce(testing::DoAll( SendFast(headers, kBody), CloseBrowserMock(&ie_mock_))); } EXPECT_CALL(ie_mock_, OnFileDownload(_, _)).Times(testing::AnyNumber()); EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, StrEq(src_url)), _, _, _, _, _)); EXPECT_CALL(ie_mock_, OnNavigateComplete2(_, testing::Field(&VARIANT::bstrVal, StrEq(src_url)))); if (in_cf) { // As mentioned above, end the test once the refreshed document is loaded. EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(src_url))) .Times(2) .WillOnce(DelayRefresh( &ie_mock_, &loop_, base::TimeDelta::FromMilliseconds(50))) .WillOnce(CloseBrowserMock(&ie_mock_)); } else { // As mentioned above, we only receive an OnLoad for the intial load, not // for the refresh. EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(src_url))) .WillOnce(DelayRefresh( &ie_mock_, &loop_, base::TimeDelta::FromMilliseconds(50))); } LaunchIENavigateAndLoop(src_url, kChromeFrameVeryLongNavigationTimeout); } // Link navigations in the same domain specified with the noreferrer flag // should be opened in the host browser. TEST_F(FullTabNavigationTest, JavascriptWindowOpenNoReferrerOpensInHost) { // 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; } MockAccEventObserver acc_observer; EXPECT_CALL(acc_observer, OnAccDocLoad(_)).Times(testing::AnyNumber()); testing::StrictMock new_window_mock; testing::StrictMock no_referrer_target_opener_window_mock; std::wstring initial_url = GetWindowOpenUrl(L"open_href_target_no_referrer.html"); std::wstring parent_url = GetTestUrl( L"open_href_target_no_referrer.html"); std::wstring new_window_url = GetSimplePageUrl(); ie_mock_.ExpectNavigation(false, initial_url); EXPECT_CALL(ie_mock_, OnLoad(false, StrEq(initial_url))); EXPECT_CALL(acc_observer, OnAccDocLoad(TabContentsTitleEq(GetWindowOpenTitle()))) .WillOnce(AccLeftClick(AccObjectMatcher())) .RetiresOnSaturation(); ie_mock_.ExpectNewWindow(&no_referrer_target_opener_window_mock); no_referrer_target_opener_window_mock.ExpectNavigation(true, parent_url); server_mock_.ExpectAndServeRequest(CFInvocation::MetaTag(), parent_url); server_mock_.ExpectAndServeRequest(CFInvocation::None(), new_window_url); server_mock_.ExpectAndServeRequest(CFInvocation::None(), initial_url); EXPECT_CALL(no_referrer_target_opener_window_mock, OnLoad(false, StrEq(parent_url))) .Times(testing::AnyNumber()); EXPECT_CALL(no_referrer_target_opener_window_mock, OnLoad(true, StrEq(parent_url))) .WillOnce(DelayAccDoDefaultActionInRenderer( &no_referrer_target_opener_window_mock, AccObjectMatcher(L"", L"link"), 1000)); // The parent window is in CF and opens a child window with the no referrer // flag in which case it should open in IE. no_referrer_target_opener_window_mock.ExpectNewWindow(&new_window_mock); new_window_mock.ExpectNavigation(false, new_window_url); EXPECT_CALL(new_window_mock, OnFileDownload(_, _)) .Times(testing::AnyNumber()); EXPECT_CALL(new_window_mock, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, testing::HasSubstr(L"attach")), _, _, _, _, _)); EXPECT_CALL(new_window_mock, OnNavigateComplete2(_, testing::Field(&VARIANT::bstrVal, testing::HasSubstr(L"attach")))) .Times(testing::AtMost(1)); EXPECT_CALL(new_window_mock, OnLoad(false, StrEq(new_window_url))) .WillOnce(CloseBrowserMock(&new_window_mock)); EXPECT_CALL(new_window_mock, OnQuit()) .WillOnce(CloseBrowserMock( &no_referrer_target_opener_window_mock)); EXPECT_CALL(no_referrer_target_opener_window_mock, OnQuit()) .WillOnce(CloseBrowserMock(&ie_mock_)); LaunchIENavigateAndLoop(initial_url, kChromeFrameVeryLongNavigationTimeout); } } // namespace chrome_frame_test