| OLD | NEW |
| (Empty) | |
| 1 // Copyright (c) 2010 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/scoped_comptr_win.h" |
| 8 #include "base/win_util.h" |
| 9 #include "chrome_frame/test/chrome_frame_test_utils.h" |
| 10 #include "chrome_frame/test/mock_ie_event_sink_actions.h" |
| 11 #include "chrome_frame/test/mock_ie_event_sink_test.h" |
| 12 |
| 13 // Needed for CreateFunctor. |
| 14 #define GMOCK_MUTANT_INCLUDE_LATE_OBJECT_BINDING |
| 15 #include "testing/gmock_mutant.h" |
| 16 |
| 17 using testing::_; |
| 18 using testing::InSequence; |
| 19 using testing::StrEq; |
| 20 |
| 21 namespace chrome_frame_test { |
| 22 |
| 23 const wchar_t tab_enter_keys[] = { VK_TAB, VK_RETURN, 0 }; |
| 24 |
| 25 // Test fixture for navigation-related tests. Each test is run thrice: IE, CF |
| 26 // with meta tag invocation, and CF with http header invocation. This is |
| 27 // accomplished by using gTest's parameterized test. |
| 28 class FullTabNavigationTest |
| 29 : public MockIEEventSinkTest, public testing::TestWithParam<CFInvocation> { |
| 30 public: |
| 31 FullTabNavigationTest() {} |
| 32 }; |
| 33 |
| 34 // Instantiate each test case. Instead of doing in one statement, it is split |
| 35 // into three so gTest prints nicer names. |
| 36 INSTANTIATE_TEST_CASE_P(IE, FullTabNavigationTest, testing::Values( |
| 37 CFInvocation(CFInvocation::NONE))); |
| 38 INSTANTIATE_TEST_CASE_P(MetaTag, FullTabNavigationTest, testing::Values( |
| 39 CFInvocation(CFInvocation::META_TAG))); |
| 40 INSTANTIATE_TEST_CASE_P(HttpHeader, FullTabNavigationTest, testing::Values( |
| 41 CFInvocation(CFInvocation::HTTP_HEADER))); |
| 42 |
| 43 // This tests navigation to a typed URL. |
| 44 TEST_P(FullTabNavigationTest, FLAKY_TypeUrl) { |
| 45 ie_mock_.ExpectNavigation(IN_IE, GetSimplePageUrl()); |
| 46 server_mock_.ExpectAndServeRequest(CFInvocation::None(), GetSimplePageUrl()); |
| 47 EXPECT_CALL(ie_mock_, OnLoad(IN_IE, StrEq(GetSimplePageUrl()))) |
| 48 .WillOnce(testing::DoAll( |
| 49 SetFocusToRenderer(&ie_mock_), |
| 50 TypeUrlInAddressBar(&loop_, GetAnchorPageUrl(0), 1500))); |
| 51 |
| 52 bool in_cf = GetParam().invokes_cf(); |
| 53 ie_mock_.ExpectNavigation(in_cf, GetAnchorPageUrl(0)); |
| 54 server_mock_.ExpectAndServeRequest(GetParam(), GetAnchorPageUrl(0)); |
| 55 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(0)))) |
| 56 .WillOnce(CloseBrowserMock(&ie_mock_)); |
| 57 |
| 58 LaunchIEAndNavigate(GetSimplePageUrl()); |
| 59 } |
| 60 |
| 61 // This tests navigation to a typed URL containing an anchor/fragment. |
| 62 TEST_P(FullTabNavigationTest, FLAKY_TypeAnchorUrl) { |
| 63 if (IsIBrowserServicePatchEnabled()) { |
| 64 LOG(ERROR) << "Not running test. IBrowserServicePatch is in place."; |
| 65 return; |
| 66 } |
| 67 |
| 68 ie_mock_.ExpectNavigation(IN_IE, GetSimplePageUrl()); |
| 69 server_mock_.ExpectAndServeRequest(CFInvocation::None(), GetSimplePageUrl()); |
| 70 EXPECT_CALL(ie_mock_, OnLoad(IN_IE, StrEq(GetSimplePageUrl()))) |
| 71 .WillOnce(testing::DoAll( |
| 72 SetFocusToRenderer(&ie_mock_), |
| 73 TypeUrlInAddressBar(&loop_, GetAnchorPageUrl(1), 1500))); |
| 74 |
| 75 bool in_cf = GetParam().invokes_cf(); |
| 76 ie_mock_.ExpectNavigation(in_cf, GetAnchorPageUrl(1)); |
| 77 server_mock_.ExpectAndServeRequest(GetParam(), GetAnchorPageUrl(1)); |
| 78 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetAnchorPageUrl(1)))) |
| 79 .WillOnce(CloseBrowserMock(&ie_mock_)); |
| 80 |
| 81 LaunchIEAndNavigate(GetSimplePageUrl()); |
| 82 } |
| 83 |
| 84 // Tests refreshing when no cached copy is available. |
| 85 TEST_P(FullTabNavigationTest, FLAKY_RefreshNoCachedCopy) { |
| 86 bool in_cf = GetParam().invokes_cf(); |
| 87 // Unfortunately it is difficult to verify that both the IE events and |
| 88 // the server requests are correct if the test is in sequence like this one. |
| 89 // This is because the server request happens sometime in the middle of the |
| 90 // IE events. Therefore we will just use the server events for this one. |
| 91 ie_mock_.ExpectAnyNavigations(); |
| 92 // This test needs to be in sequence because we are expecting the same events. |
| 93 InSequence expect_in_scope_for_sequence; |
| 94 |
| 95 testing::Cardinality initial_req_cardinality = testing::Exactly(1); |
| 96 // TODO(kkania): Remove this allowance for double request on meta tag when no |
| 97 // longer necessary. |
| 98 if (GetParam().type() == CFInvocation::META_TAG) |
| 99 initial_req_cardinality = testing::Between(1, 2); |
| 100 EXPECT_CALL(server_mock_, Get(_, UrlPathEq(GetSimplePageUrl()), _)) |
| 101 .Times(initial_req_cardinality) |
| 102 .WillRepeatedly(SendResponse(&server_mock_, GetParam())); |
| 103 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetSimplePageUrl()))) |
| 104 .WillOnce(testing::DoAll( |
| 105 SetFocusToRenderer(&ie_mock_), |
| 106 DelayRefresh(&ie_mock_, &loop_, 0))); |
| 107 |
| 108 if (in_cf) { |
| 109 server_mock_.ExpectAndServeRequest(GetParam(), GetSimplePageUrl()); |
| 110 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetSimplePageUrl()))) |
| 111 .WillOnce(testing::DoAll( |
| 112 VerifyAddressBarUrl(&ie_mock_), |
| 113 CloseBrowserMock(&ie_mock_))); |
| 114 } else { |
| 115 EXPECT_CALL(server_mock_, Get(_, UrlPathEq(GetSimplePageUrl()), _)) |
| 116 .WillOnce(CloseBrowserMock(&ie_mock_)); |
| 117 // For some reason IE does not trigger another load after this refresh. |
| 118 } |
| 119 |
| 120 LaunchIENavigateAndLoop(GetSimplePageUrl(), 5); |
| 121 } |
| 122 |
| 123 // Tests refreshing when a cached copy is available. |
| 124 TEST_P(FullTabNavigationTest, FLAKY_RefreshWithCachedCopy) { |
| 125 bool in_cf = GetParam().invokes_cf(); |
| 126 ie_mock_.ExpectAnyNavigations(); |
| 127 InSequence expect_in_scope_for_sequence; |
| 128 |
| 129 testing::Cardinality initial_req_cardinality = testing::Exactly(1); |
| 130 // TODO(kkania): Remove this allowance for double request on meta tag when no |
| 131 // longer necessary. |
| 132 if (GetParam().type() == CFInvocation::META_TAG) |
| 133 initial_req_cardinality = testing::Between(1, 2); |
| 134 EXPECT_CALL(server_mock_, Get(_, UrlPathEq(GetSimplePageUrl()), _)) |
| 135 .Times(initial_req_cardinality) |
| 136 .WillRepeatedly(SendAllowCacheResponse(&server_mock_, GetParam())); |
| 137 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetSimplePageUrl()))) |
| 138 .WillOnce(testing::DoAll( |
| 139 SetFocusToRenderer(&ie_mock_), |
| 140 DelayRefresh(&ie_mock_, &loop_, 0))); |
| 141 |
| 142 if (in_cf) { |
| 143 // For some reason IE7 requests the resource again. |
| 144 if (GetInstalledIEVersion() == IE_7) { |
| 145 server_mock_.ExpectAndServeRequest(GetParam(), GetSimplePageUrl()); |
| 146 } |
| 147 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(GetSimplePageUrl()))) |
| 148 .WillOnce(testing::DoAll( |
| 149 SetFocusToRenderer(&ie_mock_), |
| 150 CloseBrowserMock(&ie_mock_))); |
| 151 } else { |
| 152 // For some reason IE still requests the resource again, but does not |
| 153 // trigger another load. |
| 154 EXPECT_CALL(server_mock_, Get(_, UrlPathEq(GetSimplePageUrl()), _)) |
| 155 .WillOnce(CloseBrowserMock(&ie_mock_)); |
| 156 } |
| 157 |
| 158 LaunchIEAndNavigate(GetSimplePageUrl()); |
| 159 } |
| 160 |
| 161 // Test that multiple back and forward requests work. |
| 162 TEST_P(FullTabNavigationTest, MultipleBackForward) { |
| 163 std::wstring page1 = GetSimplePageUrl(); |
| 164 std::wstring page2 = GetLinkPageUrl(); |
| 165 std::wstring page3 = GetAnchorPageUrl(0); |
| 166 bool in_cf = GetParam().invokes_cf(); |
| 167 server_mock_.ExpectAndServeAnyRequests(GetParam()); |
| 168 InSequence expect_in_sequence_for_scope; |
| 169 |
| 170 // Navigate to url 2 after the previous navigation is complete. |
| 171 ie_mock_.ExpectNavigation(in_cf, page1); |
| 172 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page1))) |
| 173 .WillOnce(testing::DoAll( |
| 174 VerifyAddressBarUrl(&ie_mock_), |
| 175 Navigate(&ie_mock_, page2))); |
| 176 |
| 177 // Navigate to url 3 after the previous navigation is complete. |
| 178 ie_mock_.ExpectNavigation(in_cf, page2); |
| 179 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page2))) |
| 180 .WillOnce(testing::DoAll( |
| 181 VerifyAddressBarUrl(&ie_mock_), |
| 182 Navigate(&ie_mock_, page3))); |
| 183 |
| 184 // We have reached url 3 and have two back entries for url 1 & 2. |
| 185 // Go back to url 2 now. |
| 186 ie_mock_.ExpectNavigation(in_cf, page3); |
| 187 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page3))) |
| 188 .WillOnce(testing::DoAll( |
| 189 VerifyAddressBarUrl(&ie_mock_), |
| 190 DelayGoBack(&ie_mock_, &loop_, 0))); |
| 191 |
| 192 // We have reached url 2 and have 1 back & 1 forward entries for url 1 & 3. |
| 193 // Go back to url 1 now. |
| 194 ie_mock_.ExpectNavigation(in_cf, page2); |
| 195 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page2))) |
| 196 .WillOnce(testing::DoAll( |
| 197 VerifyAddressBarUrl(&ie_mock_), |
| 198 DelayGoBack(&ie_mock_, &loop_, 0))); |
| 199 |
| 200 // We have reached url 1 and have 0 back & 2 forward entries for url 2 & 3. |
| 201 // Go forward to url 2 now. |
| 202 ie_mock_.ExpectNavigation(in_cf, page1); |
| 203 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page1))) |
| 204 .WillOnce(testing::DoAll( |
| 205 VerifyAddressBarUrl(&ie_mock_), |
| 206 DelayGoForward(&ie_mock_, &loop_, 0))); |
| 207 |
| 208 // We have reached url 2 and have 1 back & 1 forward entries for url 1 & 3. |
| 209 // Go forward to url 3 now. |
| 210 ie_mock_.ExpectNavigation(in_cf, page2); |
| 211 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page2))) |
| 212 .WillOnce(testing::DoAll( |
| 213 VerifyAddressBarUrl(&ie_mock_), |
| 214 DelayGoForward(&ie_mock_, &loop_, 0))); |
| 215 |
| 216 // We have reached url 2 and have 1 back & 1 forward entries for url 1 & 3. |
| 217 ie_mock_.ExpectNavigation(in_cf, page3); |
| 218 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(page3))) |
| 219 .WillOnce(testing::DoAll( |
| 220 VerifyAddressBarUrl(&ie_mock_), |
| 221 CloseBrowserMock(&ie_mock_))); |
| 222 |
| 223 LaunchIEAndNavigate(page1); |
| 224 } |
| 225 |
| 226 // Test multiple back and forward operations among urls with anchors. |
| 227 // Marking this test FLAKY as it fails at times on the buildbot. |
| 228 // http://code.google.com/p/chromium/issues/detail?id=26549 |
| 229 TEST_P(FullTabNavigationTest, FLAKY_BackForwardAnchor) { |
| 230 if (!GetParam().invokes_cf()) { |
| 231 DLOG(ERROR) << "Test not implemented yet for IE."; |
| 232 return; |
| 233 } |
| 234 std::wstring kAnchorUrl = GetTestUrl(L"anchor.html"); |
| 235 std::wstring kAnchor1Url = GetTestUrl(L"anchor.html#a1"); |
| 236 std::wstring kAnchor2Url = GetTestUrl(L"anchor.html#a2"); |
| 237 std::wstring kAnchor3Url = GetTestUrl(L"anchor.html#a3"); |
| 238 bool in_cf = GetParam().invokes_cf(); |
| 239 server_mock_.ExpectAndServeAnyRequests(GetParam()); |
| 240 InSequence expect_in_sequence_for_scope; |
| 241 |
| 242 // Navigate to anchor 1: |
| 243 // - First set focus to chrome renderer window |
| 244 // Call WebBrowserEventSink::SetFocusToRenderer only once |
| 245 // in the beginning. Calling it again will change focus from the |
| 246 // current location to an element near the simulated mouse click. |
| 247 // - Then send keyboard input of TAB + ENTER to cause navigation. |
| 248 // It's better to send input as PostDelayedTask since the Activex |
| 249 // message loop_ on the other side might be blocked when we get |
| 250 // called in Onload. |
| 251 // Back/Forward state at this point: |
| 252 // Back: 0 |
| 253 // Forward: 0 |
| 254 ie_mock_.ExpectNavigation(in_cf, kAnchorUrl); |
| 255 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kAnchorUrl))) |
| 256 .WillOnce(testing::DoAll( |
| 257 SetFocusToRenderer(&ie_mock_), |
| 258 DelaySendString(&loop_, 500, tab_enter_keys))); |
| 259 |
| 260 // Navigate to anchor 2 after the previous navigation is complete |
| 261 // Back/Forward state at this point: |
| 262 // Back: 1 (kAnchorUrl) |
| 263 // Forward: 0 |
| 264 ie_mock_.ExpectAnchorNavigation(in_cf, kAnchor1Url); |
| 265 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kAnchor1Url))) |
| 266 .WillOnce(testing::DoAll( |
| 267 VerifyAddressBarUrl(&ie_mock_), |
| 268 DelaySendString(&loop_, 500, tab_enter_keys))); |
| 269 |
| 270 // Navigate to anchor 3 after the previous navigation is complete |
| 271 // Back/Forward state at this point: |
| 272 // Back: 2 (kAnchorUrl, kAnchor1Url) |
| 273 // Forward: 0 |
| 274 ie_mock_.ExpectAnchorNavigation(in_cf, kAnchor2Url); |
| 275 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kAnchor2Url))) |
| 276 .WillOnce(testing::DoAll( |
| 277 VerifyAddressBarUrl(&ie_mock_), |
| 278 DelaySendString(&loop_, 500, tab_enter_keys))); |
| 279 |
| 280 // We will reach anchor 3 once the navigation is complete, |
| 281 // then go back to anchor 2 |
| 282 // Back/Forward state at this point: |
| 283 // Back: 3 (kAnchorUrl, kAnchor1Url, kAnchor2Url) |
| 284 // Forward: 0 |
| 285 ie_mock_.ExpectAnchorNavigation(in_cf, kAnchor3Url); |
| 286 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kAnchor3Url))) |
| 287 .WillOnce(testing::DoAll( |
| 288 VerifyAddressBarUrl(&ie_mock_), |
| 289 DelayGoBack(&ie_mock_, &loop_, 0))); |
| 290 |
| 291 // We will reach anchor 2 once the navigation is complete, |
| 292 // then go back to anchor 1 |
| 293 // Back/Forward state at this point: |
| 294 // Back: 3 (kAnchorUrl, kAnchor1Url, kAnchor2Url) |
| 295 // Forward: 1 (kAnchor3Url) |
| 296 ie_mock_.ExpectNavigation(in_cf, kAnchor2Url); |
| 297 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kAnchor2Url))) |
| 298 .WillOnce(testing::DoAll( |
| 299 VerifyAddressBarUrl(&ie_mock_), |
| 300 DelayGoBack(&ie_mock_, &loop_, 0))); |
| 301 |
| 302 // We will reach anchor 1 once the navigation is complete, |
| 303 // now go forward to anchor 2 |
| 304 // Back/Forward state at this point: |
| 305 // Back: 2 (kAnchorUrl, kAnchor1Url) |
| 306 // Forward: 2 (kAnchor2Url, kAnchor3Url) |
| 307 ie_mock_.ExpectNavigation(in_cf, kAnchor1Url); |
| 308 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kAnchor1Url))) |
| 309 .WillOnce(testing::DoAll( |
| 310 VerifyAddressBarUrl(&ie_mock_), |
| 311 DelayGoForward(&ie_mock_, &loop_, 0))); |
| 312 |
| 313 // We have reached anchor 2, go forward to anchor 3 again |
| 314 // Back/Forward state at this point: |
| 315 // Back: 3 (kAnchorUrl, kAnchor1Url, kAnchor2Url) |
| 316 // Forward: 1 (kAnchor3Url) |
| 317 ie_mock_.ExpectNavigation(in_cf, kAnchor2Url); |
| 318 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kAnchor2Url))) |
| 319 .WillOnce(testing::DoAll( |
| 320 VerifyAddressBarUrl(&ie_mock_), |
| 321 DelayGoForward(&ie_mock_, &loop_, 0))); |
| 322 |
| 323 // We have gone a few steps back and forward, this should be enough for now. |
| 324 ie_mock_.ExpectNavigation(in_cf, kAnchor3Url); |
| 325 EXPECT_CALL(ie_mock_, OnLoad(in_cf, StrEq(kAnchor3Url))) |
| 326 .WillOnce(CloseBrowserMock(&ie_mock_)); |
| 327 |
| 328 LaunchIEAndNavigate(kAnchorUrl); |
| 329 } |
| 330 |
| 331 // Test that a user cannot navigate to a restricted site and that the security |
| 332 // dialog appears. |
| 333 TEST_P(FullTabNavigationTest, FLAKY_RestrictedSite) { |
| 334 if (!GetParam().invokes_cf()) |
| 335 return; |
| 336 if (IsIBrowserServicePatchEnabled()) { |
| 337 LOG(ERROR) << "Not running test. IBrowserServicePatch is in place."; |
| 338 return; |
| 339 } |
| 340 MockWindowObserver win_observer_mock; |
| 341 ScopedComPtr<IInternetSecurityManager> security_manager; |
| 342 HRESULT hr = security_manager.CreateInstance(CLSID_InternetSecurityManager); |
| 343 ASSERT_HRESULT_SUCCEEDED(hr); |
| 344 // Add the server to restricted sites zone. |
| 345 hr = security_manager->SetZoneMapping(URLZONE_UNTRUSTED, |
| 346 GetTestUrl(L"").c_str(), SZM_CREATE); |
| 347 |
| 348 EXPECT_CALL(ie_mock_, OnFileDownload(_, _)) |
| 349 .Times(testing::AnyNumber()); |
| 350 server_mock_.ExpectAndServeAnyRequests(GetParam()); |
| 351 |
| 352 ProtocolPatchMethod patch_method = GetPatchMethod(); |
| 353 |
| 354 const wchar_t* kDialogClass = L"#32770"; |
| 355 const char* kAlertDlgCaption = "Security Alert"; |
| 356 |
| 357 EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, |
| 358 testing::Field(&VARIANT::bstrVal, |
| 359 testing::StrCaseEq(GetSimplePageUrl())), _, _, _, _, _)) |
| 360 .Times(1) |
| 361 .WillOnce(WatchWindow(&win_observer_mock, kDialogClass)); |
| 362 |
| 363 if (patch_method == PATCH_METHOD_INET_PROTOCOL) { |
| 364 EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, |
| 365 testing::Field(&VARIANT::bstrVal, |
| 366 testing::HasSubstr(L"res://")), _, _, _, _, _)) |
| 367 .Times(testing::AtMost(1)); |
| 368 } |
| 369 |
| 370 EXPECT_CALL(ie_mock_, OnNavigateComplete2(_, |
| 371 testing::Field(&VARIANT::bstrVal, StrEq(GetSimplePageUrl())))) |
| 372 .Times(testing::AtMost(1)); |
| 373 |
| 374 EXPECT_CALL(win_observer_mock, OnWindowDetected(_, StrEq(kAlertDlgCaption))) |
| 375 .Times(1) |
| 376 .WillOnce(testing::DoAll( |
| 377 DoCloseWindow(), |
| 378 CloseBrowserMock(&ie_mock_))); |
| 379 |
| 380 LaunchIEAndNavigate(GetSimplePageUrl()); |
| 381 |
| 382 ASSERT_HRESULT_SUCCEEDED(security_manager->SetZoneMapping(URLZONE_UNTRUSTED, |
| 383 GetTestUrl(L"").c_str(), SZM_DELETE)); |
| 384 } |
| 385 |
| 386 // This test checks if window.open calls with target blank issued for a |
| 387 // different domain make it back to IE instead of completing the navigation |
| 388 // within Chrome. We validate this by initiating a navigation to a non existent |
| 389 // url which ensures we would get an error during navigation. |
| 390 // Marking this test as FLAKY initially as it relies on getting focus and user |
| 391 // input which don't work correctly at times. |
| 392 // http://code.google.com/p/chromium/issues/detail?id=26549 |
| 393 TEST_P(FullTabNavigationTest, FLAKY_JavascriptWindowOpenDifferentDomain) { |
| 394 std::wstring parent_url = |
| 395 GetTestUrl(L"window_open.html?http://www.nonexistent.com"); |
| 396 MockIEEventSink new_window_mock; |
| 397 ie_mock_.ExpectAnyNavigations(); |
| 398 new_window_mock.ExpectAnyNavigations(); |
| 399 server_mock_.ExpectAndServeAnyRequests(GetParam()); |
| 400 |
| 401 EXPECT_CALL(ie_mock_, OnLoad(GetParam().invokes_cf(), StrEq(parent_url))) |
| 402 .WillOnce(DelaySendDoubleClick(&ie_mock_, &loop_, 0, 10, 10)); |
| 403 |
| 404 ie_mock_.ExpectNewWindow(&new_window_mock); |
| 405 |
| 406 EXPECT_CALL(new_window_mock, OnNavigateError(_, _, _, _, _)) |
| 407 .Times(1) |
| 408 .WillOnce(CloseBrowserMock(&new_window_mock)); |
| 409 |
| 410 EXPECT_CALL(new_window_mock, OnQuit()) |
| 411 .Times(1) |
| 412 .WillOnce(CloseBrowserMock(&ie_mock_)); |
| 413 |
| 414 // OnNavigateError can take a long time to fire. |
| 415 LaunchIENavigateAndLoop(parent_url, |
| 416 kChromeFrameLongNavigationTimeoutInSeconds * 4); |
| 417 ASSERT_TRUE(new_window_mock.event_sink()->web_browser2() != NULL); |
| 418 } |
| 419 |
| 420 // Tests that a page that calls window.open can then close the popup. |
| 421 // Marking this test as FLAKY initially as it relies on getting focus and user |
| 422 // input which don't work correctly at times. |
| 423 // http://code.google.com/p/chromium/issues/detail?id=26549 |
| 424 TEST_P(FullTabNavigationTest, FLAKY_JavascriptWindowOpenCanClose) { |
| 425 std::wstring parent_url = |
| 426 GetTestUrl(L"window_open.html?simple.html"); |
| 427 MockIEEventSink new_window_mock; |
| 428 ie_mock_.ExpectAnyNavigations(); |
| 429 new_window_mock.ExpectAnyNavigations(); |
| 430 server_mock_.ExpectAndServeAnyRequests(GetParam()); |
| 431 |
| 432 // Sending 'A' to the renderer should cause window.open then window.close. |
| 433 EXPECT_CALL(ie_mock_, OnLoad(GetParam().invokes_cf(), StrEq(parent_url))) |
| 434 .WillOnce(DelaySendDoubleClick(&ie_mock_, &loop_, 0, 10, 10)); |
| 435 |
| 436 ie_mock_.ExpectNewWindow(&new_window_mock); |
| 437 |
| 438 EXPECT_CALL(new_window_mock, OnLoad(_, StrEq(GetSimplePageUrl()))) |
| 439 .Times(testing::AtMost(2)) |
| 440 .WillOnce(testing::DoAll( |
| 441 SetFocusToRenderer(&ie_mock_), |
| 442 DelaySendChar(&loop_, 500, 'C', simulate_input::NONE))) |
| 443 .WillOnce(testing::Return()); // just to stop a gmock warning |
| 444 |
| 445 EXPECT_CALL(new_window_mock, OnQuit()) |
| 446 .WillOnce(CloseBrowserMock(&ie_mock_)); |
| 447 |
| 448 LaunchIEAndNavigate(parent_url); |
| 449 } |
| 450 |
| 451 // Parameter for tests using the NavigationTransitionTest fixture. Includes two |
| 452 // pages, each with their own possible CF invocation. |
| 453 struct NavigationTransitionTestParameter { |
| 454 NavigationTransitionTestParameter(CFInvocation::Type type1, |
| 455 CFInvocation::Type type2) { |
| 456 page1_ = CFInvocation(type1); |
| 457 page2_ = CFInvocation(type2); |
| 458 } |
| 459 CFInvocation page1_; |
| 460 CFInvocation page2_; |
| 461 }; |
| 462 |
| 463 // Parameterized test fixture for tests which test navigation transitions |
| 464 // between two pages. |
| 465 class NavigationTransitionTest |
| 466 : public MockIEEventSinkTest, |
| 467 public testing::TestWithParam<NavigationTransitionTestParameter> { |
| 468 public: |
| 469 NavigationTransitionTest() {} |
| 470 |
| 471 virtual void SetUp() { |
| 472 page1_ = GetParam().page1_; |
| 473 page2_ = GetParam().page2_; |
| 474 } |
| 475 |
| 476 protected: |
| 477 CFInvocation page1_; |
| 478 CFInvocation page2_; |
| 479 }; |
| 480 |
| 481 // This instantiates each parameterized test with some of the different CF |
| 482 // invocation methods. |
| 483 // TODO(kkania): Do not allow these tests to be cache the pages. This is used |
| 484 // currently because otherwise the meta tags can cause double requests. Change |
| 485 // ExpectAndServeRequestAllowCache to ExpectAndServeRequest when allowed. |
| 486 INSTANTIATE_TEST_CASE_P( |
| 487 IEToIE, |
| 488 NavigationTransitionTest, |
| 489 testing::Values(NavigationTransitionTestParameter( |
| 490 CFInvocation::NONE, CFInvocation::NONE))); |
| 491 INSTANTIATE_TEST_CASE_P( |
| 492 IEToMetaTag, |
| 493 NavigationTransitionTest, |
| 494 testing::Values(NavigationTransitionTestParameter( |
| 495 CFInvocation::NONE, CFInvocation::META_TAG))); |
| 496 INSTANTIATE_TEST_CASE_P( |
| 497 IEToHttpHeader, |
| 498 NavigationTransitionTest, |
| 499 testing::Values(NavigationTransitionTestParameter( |
| 500 CFInvocation::NONE, CFInvocation::HTTP_HEADER))); |
| 501 INSTANTIATE_TEST_CASE_P( |
| 502 CFToCF, |
| 503 NavigationTransitionTest, |
| 504 testing::Values(NavigationTransitionTestParameter( |
| 505 CFInvocation::META_TAG, CFInvocation::META_TAG))); |
| 506 INSTANTIATE_TEST_CASE_P( |
| 507 CFToIE, |
| 508 NavigationTransitionTest, |
| 509 testing::Values(NavigationTransitionTestParameter( |
| 510 CFInvocation::META_TAG, CFInvocation::NONE))); |
| 511 |
| 512 // Test window.open calls. |
| 513 // Marking this test as FLAKY initially as it relies on getting focus and user |
| 514 // input which don't work correctly at times. |
| 515 // http://code.google.com/p/chromium/issues/detail?id=26549 |
| 516 TEST_P(NavigationTransitionTest, FLAKY_JavascriptWindowOpen) { |
| 517 std::wstring parent_url = GetTestUrl(L"window_open.html?simple.html"); |
| 518 std::wstring new_window_url = GetSimplePageUrl(); |
| 519 MockIEEventSink new_window_mock; |
| 520 |
| 521 ie_mock_.ExpectNavigation(page1_.invokes_cf(), parent_url); |
| 522 server_mock_.ExpectAndServeRequestAllowCache(page1_, parent_url); |
| 523 EXPECT_CALL(ie_mock_, OnLoad(page1_.invokes_cf(), StrEq(parent_url))) |
| 524 .WillOnce(testing::DoAll( |
| 525 DelaySendMouseClick(&ie_mock_, &loop_, 0, 10, 10, |
| 526 simulate_input::LEFT), |
| 527 DelaySendMouseClick(&ie_mock_, &loop_, 100, 10, 10, |
| 528 simulate_input::LEFT))); |
| 529 |
| 530 // If the parent window is in CF, the child will load in CF regardless of |
| 531 // whether the child page invokes CF. |
| 532 bool expect_cf = page1_.invokes_cf() || page2_.invokes_cf(); |
| 533 ie_mock_.ExpectNewWindow(&new_window_mock); |
| 534 new_window_mock.ExpectJavascriptWindowOpenNavigation(page1_.invokes_cf(), |
| 535 expect_cf, |
| 536 new_window_url); |
| 537 server_mock_.ExpectAndServeRequestAllowCache(page2_, new_window_url); |
| 538 EXPECT_CALL(new_window_mock, OnLoad(expect_cf, StrEq(new_window_url))) |
| 539 .WillOnce(testing::DoAll( |
| 540 VerifyAddressBarUrl(&new_window_mock), |
| 541 ValidateWindowSize(&new_window_mock, 10, 10, 250, 250), |
| 542 CloseBrowserMock(&new_window_mock))); |
| 543 |
| 544 EXPECT_CALL(new_window_mock, OnQuit()) |
| 545 .WillOnce(CloseBrowserMock(&ie_mock_)); |
| 546 |
| 547 LaunchIENavigateAndLoop(parent_url, |
| 548 kChromeFrameLongNavigationTimeoutInSeconds * 2); |
| 549 } |
| 550 |
| 551 // Test redirection with window.location in Javascript. |
| 552 TEST_P(NavigationTransitionTest, FLAKY_JavascriptRedirection) { |
| 553 std::wstring redirect_url = GetTestUrl(L"javascript_redirect.html"); |
| 554 |
| 555 ie_mock_.ExpectNavigation(page1_.invokes_cf(), redirect_url); |
| 556 server_mock_.ExpectAndServeRequestAllowCache(page1_, redirect_url); |
| 557 EXPECT_CALL(ie_mock_, OnLoad(page1_.invokes_cf(), StrEq(redirect_url))) |
| 558 .WillOnce(VerifyAddressBarUrl(&ie_mock_)); |
| 559 |
| 560 ie_mock_.ExpectNavigation(page2_.invokes_cf(), GetSimplePageUrl()); |
| 561 server_mock_.ExpectAndServeRequestAllowCache(page2_, GetSimplePageUrl()); |
| 562 EXPECT_CALL(ie_mock_, OnLoad(page2_.invokes_cf(), StrEq(GetSimplePageUrl()))) |
| 563 .WillOnce(testing::DoAll( |
| 564 VerifyAddressBarUrl(&ie_mock_), |
| 565 CloseBrowserMock(&ie_mock_))); |
| 566 |
| 567 LaunchIEAndNavigate(redirect_url); |
| 568 } |
| 569 |
| 570 // Test following a link by TAB + ENTER. |
| 571 TEST_P(NavigationTransitionTest, FLAKY_FollowLink) { |
| 572 if (page1_.invokes_cf() && page2_.invokes_cf() && |
| 573 GetInstalledIEVersion() > IE_6) { |
| 574 // For some reason IE 7 and 8 send two BeforeNavigate events for the second |
| 575 // page. |
| 576 return; |
| 577 } |
| 578 ie_mock_.ExpectNavigation(page1_.invokes_cf(), GetLinkPageUrl()); |
| 579 server_mock_.ExpectAndServeRequestAllowCache(page1_, GetLinkPageUrl()); |
| 580 EXPECT_CALL(ie_mock_, OnLoad(page1_.invokes_cf(), StrEq(GetLinkPageUrl()))) |
| 581 .WillOnce(testing::DoAll( |
| 582 DelaySendMouseClick(&ie_mock_, &loop_, 0, 1, 1, |
| 583 simulate_input::LEFT), |
| 584 DelaySendScanCode(&loop_, 500, VK_TAB, simulate_input::NONE), |
| 585 DelaySendScanCode(&loop_, 1000, VK_RETURN, simulate_input::NONE))); |
| 586 |
| 587 ie_mock_.ExpectNavigation(page2_.invokes_cf(), GetSimplePageUrl()); |
| 588 server_mock_.ExpectAndServeRequestAllowCache(page2_, GetSimplePageUrl()); |
| 589 EXPECT_CALL(ie_mock_, OnLoad(page2_.invokes_cf(), StrEq(GetSimplePageUrl()))) |
| 590 .WillOnce(testing::DoAll( |
| 591 VerifyAddressBarUrl(&ie_mock_), |
| 592 CloseBrowserMock(&ie_mock_))); |
| 593 |
| 594 LaunchIEAndNavigate(GetLinkPageUrl()); |
| 595 } |
| 596 |
| 597 // Basic navigation test fixture which uses the MockIEEventSink. These tests |
| 598 // are not parameterized. |
| 599 class NavigationTest : public MockIEEventSinkTest, public testing::Test { |
| 600 public: |
| 601 NavigationTest() {} |
| 602 }; |
| 603 |
| 604 // gMock matcher which tests if a url is blank. |
| 605 MATCHER(BlankUrl, "is \"\" or NULL") { |
| 606 return arg == NULL || wcslen(arg) == 0; |
| 607 } |
| 608 |
| 609 // Test navigation to a disallowed url. |
| 610 TEST_F(NavigationTest, DisallowedUrl) { |
| 611 // If a navigation fails then IE issues a navigation to an interstitial |
| 612 // page. Catch this to track navigation errors as the NavigateError |
| 613 // notification does not seem to fire reliably. |
| 614 const wchar_t disallowed_url[] = L"gcf:file:///C:/"; |
| 615 |
| 616 EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, |
| 617 StrEq(disallowed_url)), |
| 618 _, _, _, _, _)); |
| 619 EXPECT_CALL(ie_mock_, OnLoad(IN_IE, BlankUrl())) |
| 620 .Times(testing::AtMost(1)); |
| 621 EXPECT_CALL(ie_mock_, OnBeforeNavigate2(_, testing::Field(&VARIANT::bstrVal, |
| 622 testing::StartsWith(L"res:")), |
| 623 _, _, _, _, _)); |
| 624 EXPECT_CALL(ie_mock_, OnFileDownload(VARIANT_TRUE, _)) |
| 625 .Times(testing::AnyNumber()) |
| 626 .WillRepeatedly(testing::Return()); |
| 627 EXPECT_CALL(ie_mock_, OnNavigateComplete2(_, testing::Field(&VARIANT::bstrVal, |
| 628 StrEq(disallowed_url)))); |
| 629 // Although we expect a load event for this, we should never receive a |
| 630 // corresponding GET request. |
| 631 EXPECT_CALL(ie_mock_, OnLoad(IN_IE, StrEq(disallowed_url))) |
| 632 .WillOnce(CloseBrowserMock(&ie_mock_)); |
| 633 |
| 634 LaunchIEAndNavigate(disallowed_url); |
| 635 } |
| 636 |
| 637 // NOTE: This test is currently disabled as we haven't finished implementing |
| 638 // support for this yet. The test (as written) works fine for IE. CF might |
| 639 // have a different set of requirements once we fully support this and hence |
| 640 // the test might need some refining before being enabled. |
| 641 TEST_F(NavigationTest, DISABLED_DownloadInNewWindow) { |
| 642 MockIEEventSink new_window_mock; |
| 643 std::wstring kDownloadFromNewWin = |
| 644 GetTestUrl(L"full_tab_download_from_new_window.html"); |
| 645 |
| 646 ie_mock_.ExpectNavigation(IN_CF, kDownloadFromNewWin); |
| 647 |
| 648 EXPECT_CALL(ie_mock_, OnNewWindow3(_, _, _, _, _)); |
| 649 |
| 650 EXPECT_CALL(ie_mock_, OnNewBrowserWindow(_, _)) |
| 651 .WillOnce(testing::WithArgs<0>(testing::Invoke(testing::CreateFunctor( |
| 652 &new_window_mock, &MockIEEventSink::Attach)))); |
| 653 EXPECT_CALL(new_window_mock, OnBeforeNavigate2(_, _, _, _, _, _, _)); |
| 654 |
| 655 EXPECT_CALL(new_window_mock, OnFileDownload(VARIANT_FALSE, _)) |
| 656 .Times(2) |
| 657 .WillRepeatedly(CloseBrowserMock(&new_window_mock)); |
| 658 |
| 659 EXPECT_CALL(new_window_mock, OnNavigateComplete2(_, _)); |
| 660 |
| 661 EXPECT_CALL(new_window_mock, OnQuit()).WillOnce(CloseBrowserMock(&ie_mock_)); |
| 662 |
| 663 LaunchIEAndNavigate(kDownloadFromNewWin); |
| 664 } |
| 665 |
| 666 TEST_F(NavigationTest, KILL) { |
| 667 ie_mock_.ExpectAnyNavigations(); |
| 668 LaunchIENavigateAndLoop(GetSimplePageUrl(), 4); |
| 669 } |
| 670 |
| 671 } // namespace chrome_frame_test |
| OLD | NEW |