OLD | NEW |
| (Empty) |
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 | |
OLD | NEW |