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