- add sources.
[platform/framework/web/crosswalk.git] / src / chrome_frame / test / navigation_test.cc
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(file_util::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