1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <string> 6 7 #include "base/file_util.h" 8 #include "base/test/test_file_util.h" 9 #include "base/win/scoped_comptr.h" 10 #include "base/win/windows_version.h" 11 #include "chrome_frame/test/chrome_frame_test_utils.h" 12 #include "chrome_frame/test/chrome_frame_ui_test_utils.h" 13 #include "chrome_frame/test/mock_ie_event_sink_actions.h" 14 #include "chrome_frame/test/mock_ie_event_sink_test.h" 15 #include "net/http/http_util.h" 16 17 // Needed for CreateFunctor. 18 #define GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING 19 #include "testing/gmock_mutant.h" 20 21 using testing::InSequence; 22 using testing::StrEq; 23 using testing::_; 24 25 namespace chrome_frame_test { 26 27 // Test fixture for navigation-related tests. Each test is run thrice: IE, CF 28 // with meta tag invocation, and CF with http header invocation. This is 29 // accomplished by using gTest's parameterized test. 30 class FullTabNavigationTest 31 : public MockIEEventSinkTest, public testing::TestWithParam<CFInvocation> { 32 public: 33 FullTabNavigationTest() {} 34 }; 35 36 // Instantiate each test case. Instead of doing in one statement, it is split 37 // into three so gTest prints nicer names. 38 INSTANTIATE_TEST_CASE_P(IE, FullTabNavigationTest, testing::Values( 39 CFInvocation(CFInvocation::NONE))); 40 INSTANTIATE_TEST_CASE_P(MetaTag, FullTabNavigationTest, testing::Values( 41 CFInvocation(CFInvocation::META_TAG))); 42 INSTANTIATE_TEST_CASE_P(HttpHeader, FullTabNavigationTest, testing::Values( 43 CFInvocation(CFInvocation::HTTP_HEADER))); 44 45 // This tests navigation to a typed URL. 46 TEST_P(FullTabNavigationTest, TypeUrl) { 47 MockAccEventObserver acc_observer; 48 EXPECT_CALL(acc_observer, OnAccDocLoad(_)).Times(testing::AnyNumber()); 49 AccObjectMatcher address_matcher(L"Address*", L"editable text"); 50 AccObjectMatcher go_matcher(L"Go*", L"push button"); 51 52 ie_mock_.ExpectNavigation(IN_IE, GetSimplePageUrl()); 53 server_mock_.ExpectAndServeRequest(CFInvocation::None(), GetSimplePageUrl()); 54 // Enter the new url into the address bar. 55 EXPECT_CALL(ie_mock_, OnLoad(IN_IE, StrEq(GetSimplePageUrl()))) 56 .WillOnce(testing::DoAll( 57 AccSetValueInBrowser(&ie_mock_, address_matcher, GetAnchorPageUrl(0)), 58 AccWatchForOneValueChange(&acc_observer, address_matcher))); 59 // Click the go button once the address has changed. 60 EXPECT_CALL(acc_observer, OnAccValueChange(_, _, GetAnchorPageUrl(0))) 61 .WillOnce(AccLeftClickInBrowser(&ie_mock_, go_matcher)); 62 63 bool in_cf = GetParam().invokes_cf(); 64 ie_mock_.ExpectNavigation(in_cf, GetAnchorPageUrl(0)); 65 server_mock_.ExpectAndServeRequest(GetParam(), GetAnchorPageUrl(0)); 66 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(0)))) 67 .WillOnce(CloseBrowserMock(&ie_mock_)); 68 69 LaunchIEAndNavigate(GetSimplePageUrl()); 70 } 71 72 // This tests navigation to a typed URL containing an fragment. 73 TEST_P(FullTabNavigationTest, TypeAnchorUrl) { 74 MockAccEventObserver acc_observer; 75 EXPECT_CALL(acc_observer, OnAccDocLoad(_)).Times(testing::AnyNumber()); 76 AccObjectMatcher address_matcher(L"Address*", L"editable text"); 77 AccObjectMatcher go_matcher(L"Go*", L"push button"); 78 79 ie_mock_.ExpectNavigation(IN_IE, GetSimplePageUrl()); 80 server_mock_.ExpectAndServeRequest(CFInvocation::None(), GetSimplePageUrl()); 81 82 // Enter the new url into the address bar. 83 EXPECT_CALL(ie_mock_, OnLoad(IN_IE, StrEq(GetSimplePageUrl()))) 84 .WillOnce(testing::DoAll( 85 AccSetValueInBrowser(&ie_mock_, address_matcher, GetAnchorPageUrl(1)), 86 AccWatchForOneValueChange(&acc_observer, address_matcher))); 87 // Click the go button once the address has changed. 88 EXPECT_CALL(acc_observer, OnAccValueChange(_, _, GetAnchorPageUrl(1))) 89 .WillOnce(AccLeftClickInBrowser(&ie_mock_, go_matcher)); 90 91 bool in_cf = GetParam().invokes_cf(); 92 ie_mock_.ExpectNavigation(in_cf, GetAnchorPageUrl(1)); 93 server_mock_.ExpectAndServeRequest(GetParam(), GetAnchorPageUrl(1)); 94 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(1)))) 95 .WillOnce(CloseBrowserMock(&ie_mock_)); 96 97 LaunchIEAndNavigate(GetSimplePageUrl()); 98 } 99 100 // Tests refreshing causes a page load. 101 TEST_P(FullTabNavigationTest, Refresh) { 102 if (GetInstalledIEVersion() == IE_7) { 103 LOG(ERROR) << "Test disabled for this configuration."; 104 return; 105 } 106 bool in_cf = GetParam().invokes_cf(); 107 server_mock_.ExpectAndServeAnyRequests(GetParam()); 108 InSequence expect_in_sequence_for_scope; 109 110 ie_mock_.ExpectNavigation(IN_IE, GetSimplePageUrl()); 111 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetSimplePageUrl()))) 112 .WillOnce(DelayRefresh(&ie_mock_, &loop_, base::TimeDelta())); 113 114 if (in_cf) { 115 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetSimplePageUrl()))) 116 .WillOnce(CloseBrowserMock(&ie_mock_)); 117 } else { 118 // For some reason IE still requests the resource again, but does not 119 // trigger another load. 120 EXPECT_CALL(server_mock_, Get(_, UrlPathEq(GetSimplePageUrl()), _)) 121 .WillOnce(CloseBrowserMock(&ie_mock_)); 122 } 123 124 LaunchIEAndNavigate(GetSimplePageUrl()); 125 } 126 127 // Test that multiple back and forward requests work. 128 // TODO(tsepez): http://crbug.com/83133 129 TEST_P(FullTabNavigationTest, DISABLED_MultipleBackForward) { 130 std::wstring page1 = GetSimplePageUrl(); 131 std::wstring page2 = GetLinkPageUrl(); 132 std::wstring page3 = GetAnchorPageUrl(0); 133 bool in_cf = GetParam().invokes_cf(); 134 server_mock_.ExpectAndServeAnyRequests(GetParam()); 135 InSequence expect_in_sequence_for_scope; 136 137 // Navigate to url 2 after the previous navigation is complete. 138 ie_mock_.ExpectNavigation(in_cf, page1); 139 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page1))) 140 .WillOnce(testing::DoAll( 141 VerifyAddressBarUrl(&ie_mock_), 142 Navigate(&ie_mock_, page2))); 143 144 // Navigate to url 3 after the previous navigation is complete. 145 ie_mock_.ExpectNavigation(in_cf, page2); 146 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page2))) 147 .WillOnce(testing::DoAll( 148 VerifyAddressBarUrl(&ie_mock_), 149 Navigate(&ie_mock_, page3))); 150 151 // We have reached url 3 and have two back entries for url 1 & 2. 152 // Go back to url 2 now. 153 ie_mock_.ExpectNavigation(in_cf, page3); 154 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page3))) 155 .WillOnce(testing::DoAll( 156 VerifyAddressBarUrl(&ie_mock_), 157 DelayGoBack(&ie_mock_, &loop_, base::TimeDelta()))); 158 159 // We have reached url 2 and have 1 back & 1 forward entries for url 1 & 3. 160 // Go back to url 1 now. 161 ie_mock_.ExpectNavigation(in_cf, page2); 162 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page2))) 163 .WillOnce(testing::DoAll( 164 VerifyAddressBarUrl(&ie_mock_), 165 DelayGoBack(&ie_mock_, &loop_, base::TimeDelta()))); 166 167 // We have reached url 1 and have 0 back & 2 forward entries for url 2 & 3. 168 // Go forward to url 2 now. 169 ie_mock_.ExpectNavigation(in_cf, page1); 170 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page1))) 171 .WillOnce(testing::DoAll( 172 VerifyAddressBarUrl(&ie_mock_), 173 DelayGoForward(&ie_mock_, &loop_, base::TimeDelta()))); 174 175 // We have reached url 2 and have 1 back & 1 forward entries for url 1 & 3. 176 // Go forward to url 3 now. 177 ie_mock_.ExpectNavigation(in_cf, page2); 178 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page2))) 179 .WillOnce(testing::DoAll( 180 VerifyAddressBarUrl(&ie_mock_), 181 DelayGoForward(&ie_mock_, &loop_, base::TimeDelta()))); 182 183 // We have reached url 2 and have 1 back & 1 forward entries for url 1 & 3. 184 ie_mock_.ExpectNavigation(in_cf, page3); 185 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page3))) 186 .WillOnce(testing::DoAll( 187 VerifyAddressBarUrl(&ie_mock_), 188 CloseBrowserMock(&ie_mock_))); 189 190 LaunchIENavigateAndLoop(page1, kChromeFrameLongNavigationTimeout * 2); 191 } 192 193 // Test multiple back and forward operations among urls with anchors. 194 TEST_P(FullTabNavigationTest, BackForwardAnchor) { 195 std::wstring title(GetAnchorPageTitle()); 196 bool in_cf = GetParam().invokes_cf(); 197 ie_mock_.ExpectAnyNavigations(); 198 server_mock_.ExpectAndServeAnyRequests(GetParam()); 199 MockAccEventObserver acc_observer; 200 EXPECT_CALL(acc_observer, OnAccDocLoad(_)).Times(testing::AnyNumber()); 201 202 // Navigate to anchor 1. 203 // Back/Forward state at this point: 204 // Back: 0 205 // Forward: 0 206 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(0)))) 207 .Times(testing::AtMost(1)); 208 EXPECT_CALL(acc_observer, OnAccDocLoad(TabContentsTitleEq(GetAnchorPageUrl(0), 209 title))) 210 .WillOnce(AccDoDefaultAction(AccObjectMatcher(L"*1", L"link"))) 211 .RetiresOnSaturation(); 212 213 InSequence expect_in_sequence_for_scope; 214 // Navigate to anchor 2 after the previous navigation is complete 215 // Back/Forward state at this point: 216 // Back: 1 (kAnchorUrl) 217 // Forward: 0 218 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(1)))) 219 .WillOnce(testing::DoAll( 220 VerifyAddressBarUrl(&ie_mock_), 221 AccDoDefaultActionInRenderer(&ie_mock_, 222 AccObjectMatcher(L"*2", L"link")))); 223 224 // Navigate to anchor 3 after the previous navigation is complete 225 // Back/Forward state at this point: 226 // Back: 2 (kAnchorUrl, kAnchor1Url) 227 // Forward: 0 228 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(2)))) 229 .WillOnce(testing::DoAll( 230 VerifyAddressBarUrl(&ie_mock_), 231 AccDoDefaultActionInRenderer(&ie_mock_, 232 AccObjectMatcher(L"*3", L"link")))); 233 234 // We will reach anchor 3 once the navigation is complete, 235 // then go back to anchor 2 236 // Back/Forward state at this point: 237 // Back: 3 (kAnchorUrl, kAnchor1Url, kAnchor2Url) 238 // Forward: 0 239 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(3)))) 240 .WillOnce(testing::DoAll( 241 VerifyAddressBarUrl(&ie_mock_), 242 DelayGoBack(&ie_mock_, &loop_, base::TimeDelta()))); 243 244 // We will reach anchor 2 once the navigation is complete, 245 // then go back to anchor 1 246 // Back/Forward state at this point: 247 // Back: 3 (kAnchorUrl, kAnchor1Url, kAnchor2Url) 248 // Forward: 1 (kAnchor3Url) 249 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(2)))) 250 .WillOnce(testing::DoAll( 251 VerifyAddressBarUrl(&ie_mock_), 252 DelayGoBack(&ie_mock_, &loop_, base::TimeDelta()))); 253 254 // We will reach anchor 1 once the navigation is complete, 255 // now go forward to anchor 2 256 // Back/Forward state at this point: 257 // Back: 2 (kAnchorUrl, kAnchor1Url) 258 // Forward: 2 (kAnchor2Url, kAnchor3Url) 259 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(1)))) 260 .WillOnce(testing::DoAll( 261 VerifyAddressBarUrl(&ie_mock_), 262 DelayGoForward(&ie_mock_, &loop_, base::TimeDelta()))); 263 264 // We have reached anchor 2, go forward to anchor 3 again 265 // Back/Forward state at this point: 266 // Back: 3 (kAnchorUrl, kAnchor1Url, kAnchor2Url) 267 // Forward: 1 (kAnchor3Url) 268 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(2)))) 269 .WillOnce(testing::DoAll( 270 VerifyAddressBarUrl(&ie_mock_), 271 DelayGoForward(&ie_mock_, &loop_, base::TimeDelta()))); 272 273 // We have gone a few steps back and forward, this should be enough for now. 274 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(3)))) 275 .WillOnce(CloseBrowserMock(&ie_mock_)); 276 277 LaunchIEAndNavigate(GetAnchorPageUrl(0)); 278 } 279 280 // Test that a user cannot navigate to a restricted site and that the security 281 // dialog appears. 282 TEST_P(FullTabNavigationTest, RestrictedSite) { 283 // Add the server to restricted sites zone. 284 base::win::ScopedComPtr<IInternetSecurityManager> security_manager; 285 HRESULT hr = security_manager.CreateInstance(CLSID_InternetSecurityManager); 286 ASSERT_HRESULT_SUCCEEDED(hr); 287 hr = security_manager->SetZoneMapping(URLZONE_UNTRUSTED, 288 GetTestUrl(L"").c_str(), SZM_CREATE); 289 290 EXPECT_CALL(ie_mock_, OnFileDownload(_, _)).Times(testing::AnyNumber()); 291 server_mock_.ExpectAndServeAnyRequests(GetParam()); 292 293 MockWindowObserver win_observer_mock; 294 295 // If the page is loaded in mshtml, then IE allows the page to be loaded 296 // and just shows 'Restricted sites' in the status bar. 297 if (!GetParam().invokes_cf()) { 298 ie_mock_.ExpectNavigation(IN_IE, GetSimplePageUrl()); 299 EXPECT_CALL(ie_mock_, OnLoad(IN_IE, StrEq(GetSimplePageUrl()))) 300 .Times(1) 301 .WillOnce(CloseBrowserMock(&ie_mock_)); 302 } else { 303 // If the page is being loaded in chrome frame then we will see 304 // a security dialog. 305 const char* kAlertDlgCaption = "Security Alert"; 306 win_observer_mock.WatchWindow(kAlertDlgCaption, ""); 307 308 EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, 309 testing::HasSubstr(GetSimplePageUrl())), _, _, _, _, _)) 310 .Times(testing::AtMost(2)); 311 312 EXPECT_CALL(ie_mock_, OnNavigateComplete2(_, 313 testing::Field(&VARIANT::bstrVal, StrEq(GetSimplePageUrl())))) 314 .Times(testing::AtMost(1)); 315 316 EXPECT_CALL(win_observer_mock, OnWindowOpen(_)) 317 .Times(1) 318 .WillOnce(DoCloseWindow()); 319 EXPECT_CALL(win_observer_mock, OnWindowClose(_)) 320 .Times(1) 321 .WillOnce(CloseBrowserMock(&ie_mock_)); 322 } 323 324 LaunchIEAndNavigate(GetSimplePageUrl()); 325 326 ASSERT_HRESULT_SUCCEEDED(security_manager->SetZoneMapping(URLZONE_UNTRUSTED, 327 GetTestUrl(L"").c_str(), SZM_DELETE)); 328 } 329 330 // This test checks if window.open calls with target blank issued for a 331 // different domain make it back to IE instead of completing the navigation 332 // within Chrome. We validate this by initiating a navigation to a non existent 333 // url which ensures we would get an error during navigation. 334 // Marking this disabled as it leaves behind Chrome processes, at least on 335 // IE 6 XP (http://crbug.com/48732). 336 TEST_P(FullTabNavigationTest, DISABLED_JavascriptWindowOpenDifferentDomain) { 337 if (!GetParam().invokes_cf() || GetInstalledIEVersion() == IE_7) { 338 LOG(ERROR) << "Test disabled for this configuration."; 339 return; 340 } 341 std::wstring parent_url = GetWindowOpenUrl(L"http://www.nonexistent.com"); 342 MockAccEventObserver acc_observer; 343 MockIEEventSink new_window_mock; 344 ie_mock_.ExpectAnyNavigations(); 345 new_window_mock.ExpectAnyNavigations(); 346 server_mock_.ExpectAndServeAnyRequests(GetParam()); 347 EXPECT_CALL(acc_observer, OnAccDocLoad(_)).Times(testing::AnyNumber()); 348 349 EXPECT_CALL(ie_mock_, OnLoad(GetParam().invokes_cf(), StrEq(parent_url))); 350 EXPECT_CALL(acc_observer, 351 OnAccDocLoad(TabContentsTitleEq(parent_url, 352 GetWindowOpenTitle()))) 353 .WillOnce(AccLeftClick(AccObjectMatcher())); 354 355 ie_mock_.ExpectNewWindow(&new_window_mock); 356 EXPECT_CALL(new_window_mock, OnNavigateError(_, _, _, _, _)) 357 .Times(1) 358 .WillOnce(CloseBrowserMock(&new_window_mock)); 359 360 EXPECT_CALL(new_window_mock, OnLoad(_, _)) 361 .Times(testing::AtMost(1)); 362 363 EXPECT_CALL(new_window_mock, OnQuit()) 364 .Times(1) 365 .WillOnce(CloseBrowserMock(&ie_mock_)); 366 367 // OnNavigateError can take a long time to fire. 368 LaunchIENavigateAndLoop(parent_url, kChromeFrameLongNavigationTimeout * 4); 369 ASSERT_TRUE(new_window_mock.event_sink()->web_browser2() != NULL); 370 } 371 372 // Tests that the parent window can successfully close its popup through 373 // the javascript close method. 374 TEST_P(FullTabNavigationTest, JavascriptWindowOpenCanClose) { 375 // Please see http://code.google.com/p/chromium/issues/detail?id=60987 376 // for more information on why this test is disabled for Vista with IE7. 377 if (base::win::GetVersion() == base::win::VERSION_VISTA && 378 GetInstalledIEVersion() == IE_7) { 379 LOG(INFO) << "Not running test on Vista with IE7"; 380 return; 381 } 382 383 std::wstring parent_url = GetWindowOpenUrl(L"simple.html"); 384 MockAccEventObserver acc_observer; 385 MockIEEventSink new_window_mock; 386 ie_mock_.ExpectAnyNavigations(); 387 new_window_mock.ExpectAnyNavigations(); 388 server_mock_.ExpectAndServeAnyRequests(GetParam()); 389 EXPECT_CALL(acc_observer, OnAccDocLoad(_)).Times(testing::AnyNumber()); 390 391 // Tell the page to open the popup. Some versions of IE will prevent a popup 392 // unless a click is involved. 393 EXPECT_CALL(ie_mock_, OnLoad(GetParam().invokes_cf(), StrEq(parent_url))); 394 EXPECT_CALL(acc_observer, 395 OnAccDocLoad(TabContentsTitleEq(parent_url, 396 GetWindowOpenTitle()))) 397 .WillOnce(AccLeftClick(AccObjectMatcher())); 398 399 ie_mock_.ExpectNewWindow(&new_window_mock); 400 EXPECT_CALL(new_window_mock, OnLoad(_, StrEq(GetSimplePageUrl()))) 401 .Times(testing::AtMost(2)) 402 .WillOnce(PostKeyMessageToRenderer(&ie_mock_, 'c')) // close the popup 403 .WillOnce(testing::Return()); 404 405 EXPECT_CALL(new_window_mock, OnQuit()) 406 .WillOnce(CloseBrowserMock(&ie_mock_)); 407 408 LaunchIENavigateAndLoop(parent_url, kChromeFrameLongNavigationTimeout * 2); 409 } 410 411 // Parameter for tests using the NavigationTransitionTest fixture. Includes two 412 // pages, each with their own possible CF invocation. 413 struct NavigationTransitionTestParameter { 414 NavigationTransitionTestParameter(CFInvocation::Type type1, 415 CFInvocation::Type type2) { 416 page1_ = CFInvocation(type1); 417 page2_ = CFInvocation(type2); 418 } 419 CFInvocation page1_; 420 CFInvocation page2_; 421 }; 422 423 // Parameterized test fixture for tests which test navigation transitions 424 // between two pages. 425 class NavigationTransitionTest 426 : public MockIEEventSinkTest, 427 public testing::TestWithParam<NavigationTransitionTestParameter> { 428 public: 429 NavigationTransitionTest() {} 430 431 virtual void SetUp() { 432 page1_ = GetParam().page1_; 433 page2_ = GetParam().page2_; 434 } 435 436 protected: 437 CFInvocation page1_; 438 CFInvocation page2_; 439 }; 440 441 // This instantiates each parameterized test with some of the different CF 442 // invocation methods. 443 INSTANTIATE_TEST_CASE_P( 444 IEToIE, 445 NavigationTransitionTest, 446 testing::Values(NavigationTransitionTestParameter( 447 CFInvocation::NONE, CFInvocation::NONE))); 448 INSTANTIATE_TEST_CASE_P( 449 IEToMetaTag, 450 NavigationTransitionTest, 451 testing::Values(NavigationTransitionTestParameter( 452 CFInvocation::NONE, CFInvocation::META_TAG))); 453 INSTANTIATE_TEST_CASE_P( 454 IEToHttpHeader, 455 NavigationTransitionTest, 456 testing::Values(NavigationTransitionTestParameter( 457 CFInvocation::NONE, CFInvocation::HTTP_HEADER))); 458 INSTANTIATE_TEST_CASE_P( 459 CFToCF, 460 NavigationTransitionTest, 461 testing::Values(NavigationTransitionTestParameter( 462 CFInvocation::META_TAG, CFInvocation::META_TAG))); 463 INSTANTIATE_TEST_CASE_P( 464 CFToIE, 465 NavigationTransitionTest, 466 testing::Values(NavigationTransitionTestParameter( 467 CFInvocation::META_TAG, CFInvocation::NONE))); 468 469 // Test window.open calls. 470 TEST_P(NavigationTransitionTest, JavascriptWindowOpen) { 471 // Please see http://code.google.com/p/chromium/issues/detail?id=60987 472 // for more information on why this test is disabled for Vista with IE7. 473 if (base::win::GetVersion() == base::win::VERSION_VISTA && 474 GetInstalledIEVersion() == IE_7) { 475 LOG(INFO) << "Not running test on Vista with IE7"; 476 return; 477 } 478 479 std::wstring parent_url = GetWindowOpenUrl(L"simple.html"); 480 std::wstring new_window_url = GetSimplePageUrl(); 481 MockAccEventObserver acc_observer; 482 testing::StrictMock<MockIEEventSink> new_window_mock; 483 484 EXPECT_CALL(acc_observer, OnAccDocLoad(_)).Times(testing::AnyNumber()); 485 ie_mock_.ExpectNavigation(page1_.invokes_cf(), parent_url); 486 server_mock_.ExpectAndServeRequest(page1_, parent_url); 487 EXPECT_CALL(ie_mock_, OnLoad(page1_.invokes_cf(), StrEq(parent_url))); 488 // Tell the page to open the popup. Some versions of IE will prevent a popup 489 // unless a click is involved. 490 EXPECT_CALL(acc_observer, 491 OnAccDocLoad(TabContentsTitleEq(parent_url, 492 GetWindowOpenTitle()))) 493 .WillOnce(AccLeftClick(AccObjectMatcher())); 494 495 // If the parent window is in CF, the child should always load in CF since 496 // the domain is the same. 497 bool expect_cf = page1_.invokes_cf() || page2_.invokes_cf(); 498 ie_mock_.ExpectNewWindow(&new_window_mock); 499 new_window_mock.ExpectJavascriptWindowOpenNavigation(page1_.invokes_cf(), 500 expect_cf, 501 new_window_url); 502 server_mock_.ExpectAndServeRequest(page2_, new_window_url); 503 EXPECT_CALL(new_window_mock, OnLoad(expect_cf, StrEq(new_window_url))) 504 .WillOnce(testing::DoAll( 505 ValidateWindowSize(&new_window_mock, 10, 10, 250, 250), 506 CloseBrowserMock(&new_window_mock))); 507 508 EXPECT_CALL(new_window_mock, OnQuit()) 509 .WillOnce(CloseBrowserMock(&ie_mock_)); 510 511 LaunchIENavigateAndLoop(parent_url, kChromeFrameLongNavigationTimeout * 2); 512 } 513 514 // Test redirection with window.location in Javascript. 515 // Disabled because crashes IE occasionally: http://crbug.com/48849. 516 TEST_P(NavigationTransitionTest, DISABLED_JavascriptRedirection) { 517 std::wstring redirect_url = GetTestUrl(L"javascript_redirect.html"); 518 519 ie_mock_.ExpectNavigation(page1_.invokes_cf(), redirect_url); 520 server_mock_.ExpectAndServeRequest(page1_, redirect_url); 521 EXPECT_CALL(ie_mock_, OnLoad(page1_.invokes_cf(), StrEq(redirect_url))) 522 .WillOnce(VerifyAddressBarUrl(&ie_mock_)); 523 524 ie_mock_.ExpectNavigation(page2_.invokes_cf(), GetSimplePageUrl()); 525 server_mock_.ExpectAndServeRequest(page2_, GetSimplePageUrl()); 526 EXPECT_CALL(ie_mock_, OnLoad(page2_.invokes_cf(), StrEq(GetSimplePageUrl()))) 527 .WillOnce(testing::DoAll( 528 VerifyAddressBarUrl(&ie_mock_), 529 CloseBrowserMock(&ie_mock_))); 530 531 LaunchIEAndNavigate(redirect_url); 532 } 533 534 // Test following a link. 535 TEST_P(NavigationTransitionTest, FollowLink) { 536 if (page1_.invokes_cf() && page2_.invokes_cf()) { 537 // For some reason IE 7 and 8 send two BeforeNavigate events for the second 538 // page for this case. All versions do not send the OnLoad event for the 539 // second page if both pages are renderered in CF. 540 LOG(ERROR) << "Test disabled for this configuration."; 541 return; 542 } 543 MockAccEventObserver acc_observer; 544 EXPECT_CALL(acc_observer, OnAccDocLoad(_)).Times(testing::AnyNumber()); 545 546 ie_mock_.ExpectNavigation(page1_.invokes_cf(), GetLinkPageUrl()); 547 // Two requests are made when going from CF to IE, at least on Win7 IE8. 548 EXPECT_CALL(server_mock_, Get(_, UrlPathEq(GetLinkPageUrl()), _)) 549 .Times(testing::Between(1, 2)) 550 .WillRepeatedly(SendResponse(&server_mock_, page1_)); 551 EXPECT_CALL(ie_mock_, OnLoad(page1_.invokes_cf(), StrEq(GetLinkPageUrl()))); 552 EXPECT_CALL(acc_observer, 553 OnAccDocLoad(TabContentsTitleEq(GetLinkPageUrl(), 554 GetLinkPageTitle()))) 555 .WillOnce(AccDoDefaultAction(AccObjectMatcher(L"", L"link"))) 556 .RetiresOnSaturation(); 557 558 ie_mock_.ExpectNavigation(page2_.invokes_cf(), GetSimplePageUrl()); 559 server_mock_.ExpectAndServeRequest(page2_, GetSimplePageUrl()); 560 EXPECT_CALL(ie_mock_, OnLoad(page2_.invokes_cf(), StrEq(GetSimplePageUrl()))) 561 .WillOnce(testing::DoAll( 562 VerifyAddressBarUrl(&ie_mock_), 563 CloseBrowserMock(&ie_mock_))); 564 565 LaunchIEAndNavigate(GetLinkPageUrl()); 566 } 567 568 // gMock matcher which tests if a url is blank. 569 MATCHER(BlankUrl, "is \"\" or NULL") { 570 return arg == NULL || wcslen(arg) == 0; 571 } 572 573 // Basic navigation test fixture which uses the MockIEEventSink. These tests 574 // are not parameterized. 575 class NavigationTest : public MockIEEventSinkTest, public testing::Test { 576 public: 577 NavigationTest() {} 578 579 void TestDisAllowedUrl(const wchar_t* url) { 580 // If a navigation fails then IE issues a navigation to an interstitial 581 // page. Catch this to track navigation errors as the NavigateError 582 // notification does not seem to fire reliably. 583 EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, 584 StrEq(url)), 585 _, _, _, _, _)); 586 EXPECT_CALL(ie_mock_, OnLoad(IN_IE, BlankUrl())) 587 .Times(testing::AtMost(1)); 588 EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, 589 testing::StartsWith(L"res:")), 590 _, _, _, _, _)); 591 EXPECT_CALL(ie_mock_, OnFileDownload(VARIANT_TRUE, _)) 592 .Times(testing::AnyNumber()) 593 .WillRepeatedly(testing::Return()); 594 EXPECT_CALL(ie_mock_, OnNavigateComplete2(_, 595 testing::Field(&VARIANT::bstrVal, 596 StrEq(url)))); 597 // Although we expect a load event for this, we should never receive a 598 // corresponding GET request. 599 EXPECT_CALL(ie_mock_, OnLoad(IN_IE, StrEq(url))) 600 .WillOnce(CloseBrowserMock(&ie_mock_)); 601 602 LaunchIEAndNavigate(url); 603 } 604 605 }; 606 607 // Test navigation to a disallowed gcf: url with file scheme. 608 // Times out sporadically; http://crbug.com/119718. 609 TEST_F(NavigationTest, DISABLED_GcfProtocol1) { 610 // Make sure that we are not accidently enabling gcf protocol. 611 SetConfigBool(kAllowUnsafeURLs, false); 612 TestDisAllowedUrl(L"gcf:file:///C:/"); 613 } 614 615 // Test navigation to a disallowed gcf: url with http scheme. 616 TEST_F(NavigationTest, GcfProtocol2) { 617 // Make sure that we are not accidently enabling gcf protocol. 618 SetConfigBool(kAllowUnsafeURLs, false); 619 TestDisAllowedUrl(L"gcf:http://www.google.com"); 620 } 621 622 // Test navigation to a disallowed gcf: url with https scheme. 623 TEST_F(NavigationTest, GcfProtocol3) { 624 // Make sure that we are not accidently enabling gcf protocol. 625 SetConfigBool(kAllowUnsafeURLs, false); 626 TestDisAllowedUrl(L"gcf:https://www.google.com"); 627 } 628 629 // NOTE: This test is currently disabled as we haven't finished implementing 630 // support for this yet. The test (as written) works fine for IE. CF might 631 // have a different set of requirements once we fully support this and hence 632 // the test might need some refining before being enabled. 633 TEST_F(NavigationTest, DISABLED_DownloadInNewWindow) { 634 MockIEEventSink new_window_mock; 635 std::wstring kDownloadFromNewWin = 636 GetTestUrl(L"full_tab_download_from_new_window.html"); 637 638 ie_mock_.ExpectNavigation(IN_CF, kDownloadFromNewWin); 639 640 EXPECT_CALL(ie_mock_, OnNewWindow3(_, _, _, _, _)); 641 642 EXPECT_CALL(ie_mock_, OnNewBrowserWindow(_, _)) 643 .WillOnce(testing::WithArgs<0>(testing::Invoke(testing::CreateFunctor( 644 &new_window_mock, &MockIEEventSink::Attach)))); 645 EXPECT_CALL(new_window_mock, OnBeforeNavigate2(_, _, _, _, _, _, _)); 646 647 EXPECT_CALL(new_window_mock, OnFileDownload(VARIANT_FALSE, _)) 648 .Times(2) 649 .WillRepeatedly(CloseBrowserMock(&new_window_mock)); 650 651 EXPECT_CALL(new_window_mock, OnNavigateComplete2(_, _)); 652 653 EXPECT_CALL(new_window_mock, OnQuit()).WillOnce(CloseBrowserMock(&ie_mock_)); 654 655 LaunchIEAndNavigate(kDownloadFromNewWin); 656 } 657 658 // Flaky on ie6, http://crbug.com/255098. 659 TEST_P(FullTabNavigationTest, DISABLED_FormPostBackForward) { 660 bool in_cf = GetParam().invokes_cf(); 661 // Navigate to the form-get.html page: 662 // - First set focus to chrome renderer window 663 // - Send over a character to the window. 664 // - This should initiate a form post which eventually navigates to the 665 // action.html page. 666 // Navigate backwards from the action.html page and then navigate forward 667 // from the form-get.html page. 668 std::wstring kFormPostUrl = GetTestUrl(L"form-get.html"); 669 std::wstring kFormPostActionUrl = 670 GetTestUrl(L"action.html?field1=a&field2=b&submit=Submit"); 671 std::wstring kFormPostTitle(L"ChromeFrame form submit test(GET method)"); 672 673 MockAccEventObserver acc_observer; 674 server_mock_.ExpectAndServeAnyRequests(GetParam()); 675 EXPECT_CALL(acc_observer, OnAccDocLoad(_)).Times(testing::AnyNumber()); 676 677 EXPECT_CALL(acc_observer, OnAccDocLoad(TabContentsTitleEq(kFormPostUrl, 678 kFormPostTitle))) 679 .WillOnce(AccDoDefaultAction(AccObjectMatcher(L"Submit"))) 680 .RetiresOnSaturation(); 681 682 InSequence expect_in_sequence_for_scope; 683 684 ie_mock_.ExpectNavigation(in_cf, kFormPostUrl); 685 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kFormPostUrl))); 686 687 ie_mock_.ExpectNavigationOptionalBefore(in_cf, kFormPostActionUrl); 688 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kFormPostActionUrl))) 689 .WillOnce(testing::DoAll( 690 VerifyAddressBarUrl(&ie_mock_), 691 DelayGoBack(&ie_mock_, &loop_, base::TimeDelta()))); 692 693 ie_mock_.ExpectNavigation(in_cf, kFormPostUrl); 694 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kFormPostUrl))) 695 .WillOnce(testing::DoAll( 696 VerifyAddressBarUrl(&ie_mock_), 697 DelayGoForward(&ie_mock_, &loop_, base::TimeDelta()))); 698 699 ie_mock_.ExpectNavigationOptionalBefore(in_cf, kFormPostActionUrl); 700 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kFormPostActionUrl))) 701 .WillOnce(CloseBrowserMock(&ie_mock_)); 702 703 LaunchIEAndNavigate(kFormPostUrl); 704 } 705 706 TEST_P(FullTabNavigationTest, CF_UnloadEventTest) { 707 bool in_cf = GetParam().invokes_cf(); 708 if (!in_cf) { 709 LOG(ERROR) << "Test not yet implemented."; 710 return; 711 } 712 713 std::wstring kUnloadEventTestUrl = 714 GetTestUrl(L"fulltab_before_unload_event_test.html"); 715 716 std::wstring kUnloadEventMainUrl = 717 GetTestUrl(L"fulltab_before_unload_event_main.html"); 718 719 server_mock_.ExpectAndServeAnyRequests(GetParam()); 720 InSequence expect_in_sequence_for_scope; 721 722 ie_mock_.ExpectNavigation(in_cf, kUnloadEventTestUrl); 723 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kUnloadEventTestUrl))); 724 725 ie_mock_.ExpectNavigationOptionalBefore(in_cf, kUnloadEventMainUrl); 726 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kUnloadEventMainUrl))); 727 728 EXPECT_CALL(ie_mock_, OnMessage(_, _, _)) 729 .WillOnce(CloseBrowserMock(&ie_mock_)); 730 731 LaunchIEAndNavigate(kUnloadEventTestUrl); 732 } 733 734 // Fixture for ChromeFrame download tests. 735 class FullTabDownloadTest 736 : public MockIEEventSinkTest, public testing::TestWithParam<CFInvocation> { 737 public: 738 FullTabDownloadTest() {} 739 }; 740 741 void SaveOwnerWindow(HWND* owner_window, HWND window) { 742 *owner_window = GetWindow(window, GW_OWNER); 743 } 744 745 void CloseWindow(HWND* window) { 746 if (window) 747 PostMessage(*window, WM_CLOSE, 0, 0); 748 } 749 750 // See bug http://crbug.com/36694 751 // This test does the following:- 752 // Navigates IE to a URL which in ChromeFrame. 753 // Performs a top level form post in the document 754 // In response to the POST we send over an attachment via the 755 // content-disposition header. 756 // IE brings up a file open dialog in this context. 757 // We bring up the Save dialog via accessibility and save the file 758 // and validate that all is well. 759 TEST_F(FullTabDownloadTest, CF_DownloadFileFromPost) { 760 // Please see http://code.google.com/p/chromium/issues/detail?id=60987 761 // for more information on why this test is disabled for Vista with IE7. 762 if (base::win::GetVersion() >= base::win::VERSION_VISTA) { 763 if (GetInstalledIEVersion() == IE_7) { 764 LOG(INFO) << "Not running test on Vista with IE7"; 765 return; 766 } else if (GetInstalledIEVersion() == IE_9) { 767 LOG(INFO) << "Not running test on Vista/Windows 7 with IE9"; 768 return; 769 } 770 } 771 772 chrome_frame_test::MockWindowObserver download_watcher; 773 download_watcher.WatchWindow("File Download", ""); 774 775 chrome_frame_test::MockWindowObserver save_dialog_watcher; 776 save_dialog_watcher.WatchWindow("Save As", ""); 777 778 testing::StrictMock<MockIEEventSink> download_window_mock; 779 780 EXPECT_CALL(server_mock_, Get(_, StrEq(L"/post_source.html"), _)).WillOnce( 781 SendFast( 782 "HTTP/1.1 200 OK\r\n" 783 "Content-Type: text/html\r\n", 784 "<html>" 785 "<head><meta http-equiv=\"x-ua-compatible\" content=\"chrome=1\" />" 786 " <script type=\"text/javascript\">" 787 " function onLoad() {" 788 " document.getElementById(\"myform\").submit();}</script></head>" 789 " <body onload=\"setTimeout(onLoad, 2000);\">" 790 " <form id=\"myform\" action=\"post_target.html\" method=\"POST\">" 791 "</form></body></html>")); 792 793 EXPECT_CALL(server_mock_, Post(_, StrEq(L"/post_target.html"), _)) 794 .Times(2) 795 .WillRepeatedly( 796 SendFast( 797 "HTTP/1.1 200 OK\r\n" 798 "content-disposition: attachment;filename=\"hello.txt\"\r\n" 799 "Content-Type: application/text\r\n" 800 "Cache-Control: private\r\n", 801 "hello")); 802 803 // If you want to debug this action then you may need to 804 // SendMessage(parent_window, WM_NCACTIVATE, TRUE, 0); 805 // SendMessage(parent_window, WM_COMMAND, MAKEWPARAM(0x114B, BN_CLICKED), 806 // control_window); 807 // For the uninitiated, please debug IEFrame!CDialogActivateGuard::* 808 EXPECT_CALL(download_watcher, OnWindowOpen(_)) 809 .Times(2) 810 .WillOnce(DelayAccDoDefaultAction( 811 AccObjectMatcher(L"Save", L"push button"), 812 1000)) 813 .WillOnce(testing::Return()); 814 815 EXPECT_CALL(download_watcher, OnWindowClose(_)) 816 .Times(testing::AnyNumber()); 817 818 std::wstring src_url = server_mock_.Resolve(L"/post_source.html"); 819 std::wstring tgt_url = server_mock_.Resolve(L"/post_target.html"); 820 821 EXPECT_CALL(ie_mock_, OnFileDownload(_, _)).Times(testing::AnyNumber()); 822 823 EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, 824 testing::Field(&VARIANT::bstrVal, 825 StrEq(src_url)), _, _, _, _, _)); 826 EXPECT_CALL(ie_mock_, OnNavigateComplete2(_, 827 testing::Field(&VARIANT::bstrVal, 828 StrEq(src_url)))); 829 EXPECT_CALL(ie_mock_, OnLoad(true, StrEq(src_url))) 830 .Times(testing::AnyNumber()); 831 832 ie_mock_.ExpectNewWindow(&download_window_mock); 833 EXPECT_CALL(ie_mock_, OnLoadError(StrEq(tgt_url))) 834 .Times(testing::AnyNumber()); 835 836 EXPECT_CALL(download_window_mock, OnFileDownload(_, _)) 837 .Times(testing::AnyNumber()); 838 EXPECT_CALL(download_window_mock, OnLoadError(StrEq(tgt_url))) 839 .Times(testing::AtMost(1)); 840 EXPECT_CALL(download_window_mock, OnBeforeNavigate2(_, 841 testing::Field(&VARIANT::bstrVal, 842 StrEq(tgt_url)), _, _, _, _, _)); 843 EXPECT_CALL(download_window_mock, OnLoad(false, _)); 844 EXPECT_CALL(download_window_mock, OnQuit()).Times(testing::AtMost(1)); 845 846 base::FilePath temp_file_path; 847 ASSERT_TRUE(base::CreateTemporaryFile(&temp_file_path)); 848 file_util::DieFileDie(temp_file_path, false); 849 850 temp_file_path = temp_file_path.ReplaceExtension(L"txt"); 851 file_util::DieFileDie(temp_file_path, false); 852 853 AccObjectMatcher file_name_box(L"File name:", L"editable text"); 854 855 HWND owner_window = NULL; 856 857 EXPECT_CALL(save_dialog_watcher, OnWindowOpen(_)) 858 .WillOnce(testing::DoAll( 859 testing::Invoke(testing::CreateFunctor( 860 SaveOwnerWindow, &owner_window)), 861 AccSendCharMessage(file_name_box, L'a'), 862 AccSetValue(file_name_box, temp_file_path.value()), 863 AccDoDefaultAction(AccObjectMatcher(L"Save", L"push button")))); 864 865 EXPECT_CALL(save_dialog_watcher, OnWindowClose(_)) 866 .WillOnce(testing::DoAll( 867 WaitForFileSave(temp_file_path, 3000), 868 testing::InvokeWithoutArgs( 869 testing::CreateFunctor(CloseWindow, &owner_window)), 870 CloseBrowserMock(&ie_mock_))); 871 LaunchIENavigateAndLoop(src_url, kChromeFrameVeryLongNavigationTimeout); 872 873 std::string data; 874 EXPECT_TRUE(base::ReadFileToString(temp_file_path, &data)); 875 EXPECT_EQ("hello", data); 876 file_util::DieFileDie(temp_file_path, false); 877 } 878 879 // Test fixture for testing if http header works for supported content types 880 class HttpHeaderTest : public MockIEEventSinkTest, public testing::Test { 881 public: 882 HttpHeaderTest() {} 883 884 void HeaderTestWithData(const char* content_type, const char* data) { 885 const wchar_t* relative_url = L"/header_test"; 886 const char* kHeaderFormat = 887 "HTTP/1.1 200 OK\r\n" 888 "Connection: close\r\n" 889 "Content-Type: %s\r\n" 890 "X-UA-Compatible: chrome=1\r\n"; 891 std::string header = base::StringPrintf(kHeaderFormat, content_type); 892 std::wstring url = server_mock_.Resolve(relative_url); 893 EXPECT_CALL(server_mock_, Get(_, StrEq(relative_url), _)) 894 .WillRepeatedly(SendFast(header, data)); 895 896 InSequence expect_in_sequence_for_scope; 897 898 ie_mock_.ExpectNavigation(IN_CF, url); 899 EXPECT_CALL(ie_mock_, OnLoad(IN_CF, StrEq(url))) 900 .WillOnce(CloseBrowserMock(&ie_mock_)); 901 902 LaunchIEAndNavigate(url); 903 } 904 }; 905 906 const char* kXmlContent = 907 "<tree>" 908 "<node href=\"root.htm\" text=\"Root\">" 909 "<node href=\"child1.htm\" text=\"Child 1\" />" 910 "<node href=\"child2.htm\" text=\"Child 2\" />" 911 "</node>" 912 "</tree>"; 913 914 TEST_F(HttpHeaderTest, ApplicationXhtml) { 915 HeaderTestWithData("application/xhtml+xml", kXmlContent); 916 } 917 918 TEST_F(HttpHeaderTest, ApplicationXml) { 919 HeaderTestWithData("application/xml", kXmlContent); 920 } 921 922 TEST_F(HttpHeaderTest, TextXml) { 923 HeaderTestWithData("text/xml", kXmlContent); 924 } 925 926 const char* kImageSvg = 927 "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\" " 928 "\"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">" 929 "<svg xmlns=\"http://www.w3.org/2000/svg\" width=\"100%\" height=\"100%\">" 930 "<rect height=\"100\" width=\"300\" " 931 "style=\"fill:rgb(0,0,255);stroke-width:2;\"/>" 932 "</svg>"; 933 934 TEST_F(HttpHeaderTest, DISABLED_ImageSvg) { 935 HeaderTestWithData("image/svg", kImageSvg); 936 } 937 938 TEST_F(HttpHeaderTest, ImageSvgXml) { 939 HeaderTestWithData("image/svg+xml", kImageSvg); 940 } 941 942 // Tests refreshing causes a page load. 943 TEST_P(FullTabNavigationTest, RefreshContents) { 944 bool in_cf = GetParam().invokes_cf(); 945 if (!in_cf) { 946 VLOG(1) << "Disabled for this configuration"; 947 return; 948 } 949 950 const char kHeaders[] = 951 "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n" 952 "X-UA-Compatible: chrome=1\r\nCache-control: no-cache\r\n"; 953 954 const char kBody[] = "<html><body>Hi there. Got new content?" 955 "</body></html>"; 956 957 std::wstring src_url = server_mock_.Resolve(L"/refresh_src.html"); 958 959 EXPECT_CALL(server_mock_, Get(_, StrEq(L"/refresh_src.html"), _)) 960 .Times(2) 961 .WillRepeatedly(SendFast(kHeaders, kBody)); 962 963 EXPECT_CALL(ie_mock_, OnFileDownload(_, _)).Times(testing::AnyNumber()); 964 965 EXPECT_CALL(ie_mock_, 966 OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, 967 StrEq(src_url)), 968 _, _, _, _, _)); 969 EXPECT_CALL(ie_mock_, 970 OnNavigateComplete2(_, testing::Field(&VARIANT::bstrVal, 971 StrEq(src_url)))); 972 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(src_url))) 973 .Times(2) 974 .WillOnce(DelayRefresh( 975 &ie_mock_, &loop_, base::TimeDelta::FromMilliseconds(50))) 976 .WillOnce(CloseBrowserMock(&ie_mock_)); 977 978 LaunchIENavigateAndLoop(src_url, kChromeFrameVeryLongNavigationTimeout); 979 } 980 981 class FullTabSeleniumTest 982 : public MockIEEventSinkTest, public testing::TestWithParam<CFInvocation> { 983 public: 984 FullTabSeleniumTest() 985 : MockIEEventSinkTest(1337, L"127.0.0.1", GetSeleniumTestFolder()) {} 986 }; 987 988 ACTION(VerifySeleniumCoreTestResults) { 989 int num_tests = 0; 990 int failed_tests = 0; 991 992 swscanf(arg0, L"%d/%d", &num_tests, &failed_tests); 993 994 // Currently we run total 505 tests and 8 steps fail. 995 // TODO(amit): send results as JSON, diagnose and eliminate failures. 996 EXPECT_LE(failed_tests, 15) << "Expected failures: " << 15 << 997 " Actual failures: " << failed_tests; 998 EXPECT_GE(num_tests, 500) << "Expected to run: " << 500 << " tests." << 999 " Actual number of tests run: " << num_tests; 1000 } 1001 1002 // Crashes flakily: http://crbug.com/109114 1003 // Tests refreshing causes a page load. 1004 TEST_F(FullTabSeleniumTest, DISABLED_Core) { 1005 // Please see http://code.google.com/p/chromium/issues/detail?id=60987 1006 // for more information on why this test is disabled for Vista with IE7. 1007 if (base::win::GetVersion() == base::win::VERSION_VISTA && 1008 GetInstalledIEVersion() == IE_7) { 1009 LOG(INFO) << "Not running test on Vista with IE7"; 1010 return; 1011 } 1012 1013 server_mock_.ExpectAndServeAnyRequests(CFInvocation::HttpHeader()); 1014 std::wstring url = GetTestUrl(L"core/TestRunner.html"); 1015 1016 // Expectations for TestRunner.html 1017 EXPECT_CALL(ie_mock_, OnFileDownload(_, _)).Times(testing::AnyNumber()); 1018 EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, 1019 testing::Field(&VARIANT::bstrVal, 1020 testing::StartsWith(url)), _, _, _, _, _)) 1021 .Times(testing::AnyNumber()); 1022 EXPECT_CALL(ie_mock_, OnNavigateComplete2(_, 1023 testing::Field(&VARIANT::bstrVal, 1024 testing::StartsWith(url)))) 1025 .Times(testing::AnyNumber()); 1026 EXPECT_CALL(ie_mock_, OnLoad(true, testing::StartsWith(url))) 1027 .Times(testing::AnyNumber()); 1028 1029 // Expectation for cookie test 1030 EXPECT_CALL(ie_mock_, OnLoadError(testing::StartsWith(url))) 1031 .Times(testing::AtMost(3)); 1032 1033 // Expectations for popups 1034 std::wstring attach_url_prefix = GetTestUrl(L"?attach_external_tab&"); 1035 EXPECT_CALL(ie_mock_, OnNewWindow3(_, _, _, _, 1036 testing::StartsWith(attach_url_prefix))) 1037 .Times(testing::AnyNumber()); 1038 EXPECT_CALL(ie_mock_, OnNewBrowserWindow(_, 1039 testing::StartsWith(attach_url_prefix))) 1040 .Times(testing::AnyNumber()); 1041 1042 // At the end the tests will post us a message. See _onTestSuiteComplete in 1043 // ...\src\data\selenium_core\core\scripts\selenium-testrunner.js 1044 EXPECT_CALL(ie_mock_, OnMessage(_, _, _)) 1045 .WillOnce(testing::DoAll(VerifySeleniumCoreTestResults(), 1046 CloseBrowserMock(&ie_mock_))); 1047 1048 // Selenium tests take longer to finish, lets give it 2 mins. 1049 const base::TimeDelta kSeleniumTestTimeout = base::TimeDelta::FromMinutes(2); 1050 LaunchIENavigateAndLoop(url, kSeleniumTestTimeout); 1051 } 1052 1053 // See bug http://code.google.com/p/chromium/issues/detail?id=64901 1054 // This test does the following:- 1055 // Navigates IE to a non ChromeFrame URL. 1056 // Performs a top level form post in the document 1057 // In response to the POST send over a html document containing a meta tag 1058 // This would cause IE to switch to ChromeFrame. 1059 // Refresh the page in ChromeFrame. 1060 // This should bring up a confirmation dialog which we hit yes on. This should 1061 // reissue the top level post request in response to which the html content 1062 // containing the meta tag is sent again. 1063 TEST_F(FullTabDownloadTest, TopLevelPostReissueFromChromeFramePage) { 1064 chrome_frame_test::MockWindowObserver post_reissue_watcher; 1065 post_reissue_watcher.WatchWindow("Confirm Form Resubmission", ""); 1066 1067 EXPECT_CALL(server_mock_, Get(_, StrEq(L"/post_source.html"), _)) 1068 .WillOnce(SendFast( 1069 "HTTP/1.1 200 OK\r\n" 1070 "Content-Type: text/html\r\n", 1071 "<html>" 1072 "<head>" 1073 " <script type=\"text/javascript\">" 1074 " function onLoad() {" 1075 " document.getElementById(\"myform\").submit();}</script></head>" 1076 " <body onload=\"setTimeout(onLoad, 2000);\">" 1077 " <form id=\"myform\" action=\"post_target.html\" method=\"POST\">" 1078 "</form></body></html>")); 1079 1080 EXPECT_CALL(server_mock_, Post(_, StrEq(L"/post_target.html"), _)) 1081 .Times(2) 1082 .WillRepeatedly( 1083 SendFast( 1084 "HTTP/1.1 200 OK\r\n" 1085 "Content-Type: text/html\r\n", 1086 "<html>" 1087 "<head><meta http-equiv=\"x-ua-compatible\" content=\"chrome=1\" />" 1088 "</head>" 1089 "<body> Target page in ChromeFrame </body>" 1090 "</html>")); 1091 1092 EXPECT_CALL(post_reissue_watcher, OnWindowOpen(_)) 1093 .WillOnce(DelayAccDoDefaultAction( 1094 AccObjectMatcher(L"Yes", L"push button"), 1095 1000)); 1096 1097 EXPECT_CALL(post_reissue_watcher, OnWindowClose(_)); 1098 1099 std::wstring src_url = server_mock_.Resolve(L"/post_source.html"); 1100 std::wstring tgt_url = server_mock_.Resolve(L"/post_target.html"); 1101 1102 EXPECT_CALL(ie_mock_, OnFileDownload(_, _)).Times(testing::AnyNumber()); 1103 1104 EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, 1105 testing::Field(&VARIANT::bstrVal, 1106 StrEq(src_url)), _, _, _, _, _)); 1107 EXPECT_CALL(ie_mock_, OnNavigateComplete2(_, 1108 testing::Field(&VARIANT::bstrVal, 1109 StrEq(src_url)))); 1110 EXPECT_CALL(ie_mock_, OnLoad(false, StrEq(src_url))); 1111 1112 EXPECT_CALL(ie_mock_, OnLoad(true, StrEq(tgt_url))) 1113 .Times(2) 1114 .WillOnce(DelayRefresh( 1115 &ie_mock_, &loop_, base::TimeDelta::FromMilliseconds(50))) 1116 .WillOnce(CloseBrowserMock(&ie_mock_)); 1117 1118 EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, 1119 testing::Field(&VARIANT::bstrVal, 1120 StrEq(tgt_url)), _, _, _, _, _)) 1121 .Times(2); 1122 1123 EXPECT_CALL(ie_mock_, OnNavigateComplete2(_, 1124 testing::Field(&VARIANT::bstrVal, 1125 StrEq(tgt_url)))) 1126 .Times(2); 1127 1128 LaunchIENavigateAndLoop(src_url, kChromeFrameVeryLongNavigationTimeout); 1129 } 1130 1131 MATCHER_P(UserAgentHeaderMatcher, ua_string, "") { 1132 std::string headers = arg.headers(); 1133 StringToUpperASCII(&headers); 1134 1135 std::string ua_string_to_search = ua_string; 1136 StringToUpperASCII(&ua_string_to_search); 1137 1138 net::HttpUtil::HeadersIterator it(headers.begin(), headers.end(), 1139 "\r\n"); 1140 while (it.GetNext()) { 1141 if (lstrcmpiA(it.name().c_str(), "User-Agent") == 0) { 1142 if (it.values().find(ua_string_to_search) != std::string::npos) 1143 return true; 1144 } 1145 } 1146 return false; 1147 } 1148 1149 // Tests refreshing causes a page load and that the chrome frame user agent 1150 // string is appended to the UA in the incoming top level HTTP requests. 1151 TEST_P(FullTabNavigationTest, RefreshContentsUATest) { 1152 const char kBody[] = "<html><head></head>" 1153 "<body>Hi there. Got new content?" 1154 "</body></html>"; 1155 1156 std::string headers = "HTTP/1.1 200 OK\r\nContent-Type: text/html\r\n" 1157 "Cache-control: no-cache\r\n"; 1158 bool in_cf = GetParam().invokes_cf(); 1159 if (in_cf) { 1160 headers.append("X-UA-Compatible: chrome=1\r\n"); 1161 } else { 1162 if (GetInstalledIEVersion() == IE_9) { 1163 LOG(ERROR) << "Test disabled for IE9"; 1164 return; 1165 } 1166 } 1167 1168 std::wstring src_url = server_mock_.Resolve(L"/refresh_src.html"); 1169 1170 if (in_cf) { 1171 // In the case of Chrome Frame, end the test when the second OnLoad is 1172 // fired. 1173 EXPECT_CALL(server_mock_, Get(_, StrEq(L"/refresh_src.html"), 1174 UserAgentHeaderMatcher("chromeframe"))) 1175 .Times(2) 1176 .WillRepeatedly(SendFast(headers, kBody)); 1177 } else { 1178 // In the case of IE, we never receive a second OnLoad event, so end the 1179 // test when the second request is made on the server. 1180 EXPECT_CALL(server_mock_, Get(_, StrEq(L"/refresh_src.html"), 1181 UserAgentHeaderMatcher("chromeframe"))) 1182 .Times(2) 1183 .WillOnce(SendFast(headers, kBody)) 1184 .WillOnce(testing::DoAll( 1185 SendFast(headers, kBody), 1186 CloseBrowserMock(&ie_mock_))); 1187 } 1188 1189 EXPECT_CALL(ie_mock_, OnFileDownload(_, _)).Times(testing::AnyNumber()); 1190 1191 EXPECT_CALL(ie_mock_, 1192 OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, 1193 StrEq(src_url)), 1194 _, _, _, _, _)); 1195 EXPECT_CALL(ie_mock_, 1196 OnNavigateComplete2(_, testing::Field(&VARIANT::bstrVal, 1197 StrEq(src_url)))); 1198 if (in_cf) { 1199 // As mentioned above, end the test once the refreshed document is loaded. 1200 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(src_url))) 1201 .Times(2) 1202 .WillOnce(DelayRefresh( 1203 &ie_mock_, &loop_, base::TimeDelta::FromMilliseconds(50))) 1204 .WillOnce(CloseBrowserMock(&ie_mock_)); 1205 } else { 1206 // As mentioned above, we only receive an OnLoad for the intial load, not 1207 // for the refresh. 1208 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(src_url))) 1209 .WillOnce(DelayRefresh( 1210 &ie_mock_, &loop_, base::TimeDelta::FromMilliseconds(50))); 1211 } 1212 1213 LaunchIENavigateAndLoop(src_url, kChromeFrameVeryLongNavigationTimeout); 1214 } 1215 1216 // Link navigations in the same domain specified with the noreferrer flag 1217 // should be opened in the host browser. 1218 TEST_F(FullTabNavigationTest, JavascriptWindowOpenNoReferrerOpensInHost) { 1219 // Please see http://code.google.com/p/chromium/issues/detail?id=60987 1220 // for more information on why this test is disabled for Vista with IE7. 1221 if (base::win::GetVersion() == base::win::VERSION_VISTA && 1222 GetInstalledIEVersion() == IE_7) { 1223 LOG(INFO) << "Not running test on Vista with IE7"; 1224 return; 1225 } 1226 1227 MockAccEventObserver acc_observer; 1228 EXPECT_CALL(acc_observer, OnAccDocLoad(_)).Times(testing::AnyNumber()); 1229 1230 testing::StrictMock<MockIEEventSink> new_window_mock; 1231 testing::StrictMock<MockIEEventSink> 1232 no_referrer_target_opener_window_mock; 1233 1234 std::wstring initial_url = 1235 GetWindowOpenUrl(L"open_href_target_no_referrer.html"); 1236 1237 std::wstring parent_url = GetTestUrl( 1238 L"open_href_target_no_referrer.html"); 1239 1240 std::wstring new_window_url = GetSimplePageUrl(); 1241 1242 ie_mock_.ExpectNavigation(false, initial_url); 1243 EXPECT_CALL(ie_mock_, OnLoad(false, StrEq(initial_url))); 1244 1245 EXPECT_CALL(acc_observer, 1246 OnAccDocLoad(TabContentsTitleEq(initial_url, 1247 GetWindowOpenTitle()))) 1248 .WillOnce(AccLeftClick(AccObjectMatcher())) 1249 .RetiresOnSaturation(); 1250 1251 ie_mock_.ExpectNewWindow(&no_referrer_target_opener_window_mock); 1252 1253 no_referrer_target_opener_window_mock.ExpectNavigation(true, parent_url); 1254 1255 server_mock_.ExpectAndServeRequest(CFInvocation::MetaTag(), parent_url); 1256 server_mock_.ExpectAndServeRequest(CFInvocation::None(), new_window_url); 1257 server_mock_.ExpectAndServeRequest(CFInvocation::None(), initial_url); 1258 1259 EXPECT_CALL(no_referrer_target_opener_window_mock, 1260 OnLoad(false, StrEq(parent_url))) 1261 .Times(testing::AnyNumber()); 1262 1263 EXPECT_CALL(no_referrer_target_opener_window_mock, 1264 OnLoad(true, StrEq(parent_url))) 1265 .WillOnce(DelayAccDoDefaultActionInRenderer( 1266 &no_referrer_target_opener_window_mock, 1267 AccObjectMatcher(L"", L"link"), 1000)); 1268 1269 // The parent window is in CF and opens a child window with the no referrer 1270 // flag in which case it should open in IE. 1271 no_referrer_target_opener_window_mock.ExpectNewWindow(&new_window_mock); 1272 new_window_mock.ExpectNavigation(false, new_window_url); 1273 1274 EXPECT_CALL(new_window_mock, OnFileDownload(_, _)) 1275 .Times(testing::AnyNumber()); 1276 1277 EXPECT_CALL(new_window_mock, 1278 OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, 1279 testing::HasSubstr(L"attach")), 1280 _, _, _, _, _)); 1281 EXPECT_CALL(new_window_mock, 1282 OnNavigateComplete2(_, testing::Field(&VARIANT::bstrVal, 1283 testing::HasSubstr(L"attach")))) 1284 .Times(testing::AtMost(1)); 1285 1286 EXPECT_CALL(new_window_mock, OnLoad(false, StrEq(new_window_url))) 1287 .WillOnce(CloseBrowserMock(&new_window_mock)); 1288 1289 EXPECT_CALL(new_window_mock, OnQuit()) 1290 .WillOnce(CloseBrowserMock( 1291 &no_referrer_target_opener_window_mock)); 1292 1293 EXPECT_CALL(no_referrer_target_opener_window_mock, OnQuit()) 1294 .WillOnce(CloseBrowserMock(&ie_mock_)); 1295 1296 LaunchIENavigateAndLoop(initial_url, kChromeFrameVeryLongNavigationTimeout); 1297 } 1298 1299 } // namespace chrome_frame_test 1300